일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- login
- Cluster
- vue
- Jenkins
- 클러스터
- 로그인
- ec2
- SpringBoot
- 간단
- 자동
- Zeppelin
- 설정
- EMR
- redash
- hive
- gradle
- Docker
- 자바
- 레디스
- config
- aws
- java
- 예제
- fastcampus
- Redis
- Kafka
- 젠킨스
- 머신러닝
- Mac
- spring
- Today
- Total
코알못
5분 안에 구축하는 hystrix 본문
hystrix 를 사용하고자 하는 이유는 아래와 같다!
- A 기능에 오류가 났을시 A가 복구 될 동안 더이상 호출하지 않음으로써 부하를 주고 싶지 않다. (Circuit Open)
- A 기능에 오류가 났을시 B 기능으로 대체하고 싶다. (Fallback)
- B기능 실행 중에 A 기능이 복구가 된다면 다시 A 기능을 실행 시키고 싶다.(Circuit Close)
물론 try, catch 를 이용하여 해당 기능을 만들수 있으나, 직관적으로 볼 수 있어 코드가 깔끔하고 유지보수가 어렵지 않게 된다.
자 그럼 만들어 보자 !
# build.gradle
- 아래 사이트에서 원하는 버전, 빌드 도구 선택하여 정의
dependencies {
..
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix:2.2.9.RELEASE' // hystrix
}
# Service
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
@Service
public class HystrixService {
/***
* commandKey 는 안쓰면 자동으로 메소드 명으로 지정됨
* 다른 패키지에 같은 매소드 명이 있다면 잘못 동작할 가능성이 있으니 지정 하는 것이 좋다.
* execution.isolation.thread.timeoutInMilliseconds : 해당 시간 동안 메서드가 끝나지 않으면 circuit open
* metrics.rollingStats.timeInMilliseconds : circuit open 조건 : 해당 시간 동안
* circuitBreaker.errorThresholdPercentage : circuit open 조건 : 해당 에러 퍼센트만큼 실패시 오픈
* circuitBreaker.requestVolumeThreshold : circuit open 조건 : 최소 판단 하기 위해 해당 요청 건수만큼 들어와야 한다.
* circuitBreaker.sleepWindowInMilliseconds : circuit open 시 지속 될 시간
* ms 단
* @return
*/
@HystrixCommand(commandKey = "A", fallbackMethod = "B", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "20"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
// 10 초 동안 10번 호출 중 20% 실패시(2번 실패시) 10초간 fallback 메소드 호출
// 단, 해당 메소드가 3초 안에 끝나지 않을시 fallback 메소드 호출
})
public String A(){
return "A";
}
public String B(){
return "B";
}
# controller
import com.code.service.HystrixService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
public HystrixService hystrixService;
@RequestMapping(value = "/")
public String test(){
return hystrixService.A();
}
}
# application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@EnableHystrix
@SpringBootApplication
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
셋팅을 완료 하였으면 테스트를 진행한다!
1. 정상 서비스 경우
- 서킷 브레이크가 클로즈된 상태로 A를 리턴한다.
2. 응답 시간이 3s 이상 소요시
# service
public String A(){
try{
Thread.sleep(4000);
}catch (Exception e){
log.error("### Exception");
}
return "A";
}
- 4초 뒤에 B를 응답한다.
3. 10초 안에 10번 호출하여 20% 2번 실패시 (10번 중에 2번만 errYn 을 true로 보내어 에러를 발생 시킨다.)
# controller
@RequestMapping(value = "/")
public String test(@RequestParam Boolean errYn) throws Exception{
return hystrixService.A(errYn);
}
# service
// 에러로 인식하기 위해서는 try catch 를 제거 해야함
public String A(Boolean errYn) throws Exception{
if(errYn){
throw new Exception();
}
return "A";
}
- 2번 실패에 대한 응답값은 'B' 나머지 8번은 'A' 로 나가다가 10초뒤에 에러를 발생시키지 않아도 통계상 에러 기준에 해당 되어 더이상 'A' 를 호출하지 않고 'B'를 응답한다. 그리고 10초 뒤에 A 메소드를 호출하여 응답이 정상이니 'A' 를 리턴한다.
<참고 사항>
1. [에러] Post-processing of merged bean definition failed
- 원인 : spring boot 와 spring cloud(hystrix) 버전이 호환되지 않아 발생하는 이슈
- 해결 : spring boot 버전을 낮추어(다른 문서에 2.3.X 면 된다고 함) 해결 (2.5.6 > 2.3.8.RELEASE)
2. [설정] 메소드 내에 응답 시간이 5s 이상 걸리고, timeout 시간이 3s 로 되어 있어도 이전 연결을 끊지 않고 5s 뒤에 연결이 끊어지므로 (= 5초 뒤에 fallback 메소드 호출하여 응답) http client time out 설정을 하는것이 좋다.
3. [설정] hystrix 설정을 메소드 단위가 아니라 전체적으로 적용하고 싶다면 application.yml에 정의 하면 된다.
# application.yml
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
아래와 같이 application.yml 에서 commendKey 별로 적용도 가능하다.
hystrix:
command:
A:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
:: https://github.com/works-code/hystrix
'JAVA' 카테고리의 다른 글
5분 안에 구축하는 hystrix - Turbine (0) | 2022.01.30 |
---|---|
5분 안에 구축하는 hystrix - Dashboard 연동 (0) | 2022.01.30 |
하나의 브라우저에 멀티 세션(유저) 로그인 기능 구현 (0) | 2022.01.16 |
5분안에 구축하는 OAuth 서버 - 04 (5) | 2022.01.01 |
5분안에 구축하는 OAuth 서버 - 03 (1) | 2021.12.30 |