Backend/MSA
MSA 장애 처리 및 분산 추적
chjysm
2024. 4. 23. 19:54
MSA 에서
하나의 요청에 USER => ORDER => Category 으로 MS 간 작업중 User 는 정상 처리,
Order 에서 오류가 발생한 경우의 장애 처리를 공부해보자!
기본적으로는 정상 동작 하는 서비스의 결과 만 제공하고, 오류 발생한 서비스의 결과는 제외하여 제공하는 식인듯...
장애 처리 - CircuitBreaker( Resilinece4j )
- 장애가 발생하는 서비스의 반복적인 호출이 되지 못하게 차단
- 특정 서비스가 정상적으로 동작하지 않는 경우 다른 기능으로 대체 수행 => 장애 회피
- circuitBreaker 가 open : 실패하여 circuitBreaker 가 개입한다는 뜻
- circuitBreaker 가 close : 정상 동작하여 circuitBreaker 가 개입하지 않는다는 뜻
1. 디펜던시 추가
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
2. Config 설정( 선택 )
@Configuration
public class Resilience4JConfig {
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> globalCustomConfig(){
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(4) // 실패시 open 할 % 기본 : 50
.waitDurationInOpenState(Duration.ofSeconds(1)) // open 지속시간 기본 60초
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) // close 시 통화 결과 창 유형
.slidingWindowSize(2) // close 시 호출 결과 창 크기 설정 기본 : 100
.build();
TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(4)) // future 의 timeLimit 넘기면 circuitBreaker 온 기본 : 1초
.build();
return factory -> factory.configureDefault(
id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(timeLimiterConfig)
.circuitBreakerConfig(circuitBreakerConfig)
.build()
);
}
}
3. 사용
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitBreaker");
List<ResponseOrder> orders = circuitBreaker.run(
() -> orderServiceClient.getOrders(userId),
throwable -> new ArrayList<>()
);
분산 추적 - zipkin
- 요청이 어떻게 실행 되고 어느 단계를 거쳐서 어떠한 마이크로서비스로 이동이 되는가 추적한다.
- 분산 환경에서의 시스템 병목 현상 파악
- Kafka 와 같이 독립적인 서버이다.
- 기본 9411 포트로 구동한다.
구성
- Span
- 하나의 요청에 사용되는 작업의 단위(ex. USER => ORDER => Category)
- 64 bit unique ID
- Trace
- 트리 구조로 이뤄진 Span 셋
- 하나의 요청에 대한 같은 Trace ID 발급
1. zipkin 다운로드 및 서버 구동
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
2. 디펜던시 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-micrometer</artifactId>
</dependency>
3. yml 파일 수정
management:
tracing:
sampling:
probability: 1.0 # 발생된 로그를 어느 빈도수로 zipkin 애 전달하겠는가 1.0 = 100%
propagation:
consume: B3
produce: B3_MULTI
zipkin:
tracing:
endpoint: "http://localhost:9411/api/v2/spans"