Microservice 끼리 통신하기 위해서 RestTemplate , FeignClient 를 사용했었다.
즉 복구가 된다면 이전처럼 흐름을 바꿔주면 된다.
즉 연쇄적으로 연결되어 있는 Microservice에 문제가 생기더라도 해당하는 Microservice 만큼은 정상적으로 작동할 수 있도록 한다.
원래는 Netflix Hystrix 의존성을 추가하지만 해당 라이브러리는 더이상 수정을 하지 않기 때문에 Resilience4j 라는 의존성을 추가하면 된다.
// UserServiceImpl.getOrder()
// List<ResponseOrder> orderList = orderServiceClient.getOrders(userId);
// CircuitBreaker 적용 코드
// DI 해서 사용
CircuitBreakerFactory circuitBreakerFactory;
// 문제가 생겼을 경우 throwable -> new ArrayList<>()
List<ResponseOrder> orderList =
circuitBreaker.run(() -> orderServiceClient.getOrders(userId),
throwable -> new ArrayList<>());
@Configuration
public class Resilience4JConfig {
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> globalCustomConfiguration() {
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(4)
.waitDurationInOpenState(Duration.ofMillis(1000))
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
.slidingWindowSize(2) // 2번의 카운트가 저장된다.
.build();
TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(4))
.build();
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(timeLimiterConfig)
.circuitBreakerConfig(circuitBreakerConfig)
.build()
);
}
}
Custom 하더라도 똑같이 동작하고, 만약 order-service 서버가 정상적으로 기동되고 있다면 주문내역(orders) 부분은 정상적으로 출력이 된다.
더이상 연쇄적인 문제를 발생하지 않도록 CircuitBreaker 를 배워봤다.
여러개의 서비스가 연결되어 있고 필요한 정보는 RestTemplate , FeignClient 을 사용해서 데이터를 공유하고 전달할 수 있었다.
하나의 서비스가 시작이 되고 끝이 날 때 여러 Microservice 가 연결이 될 수 있기 떄문에 누가 누구를 거치고 어디가 문제가 되었는지 확인하는 것이 중요하다.
그런것을 확인하고 log 로 남기는 것이 Zipkin 이라고 생각하면 된다.
정리하면 새로운 요청이 있을 때 Trace 는 같지만 Span 은 달라진다.
terminal 에서 zipkin 서버를 설치
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-micrometer</artifactId>
</dependency>
Zipkin 서버에 가서 TraceID 를 입력해서 조회할 수 있고, service 의 이름을 검색해서 추적하거나 Dependencies 로도 추적할 수 있다.
만약 order-service 에서 장애(예외)가 발생했다면 똑같이 user-service 와 order-service 의 TraceID 는 서로 같지만 SpanID 는 다르다.
장애가 발생했을 때도 어디서 발생했고 log 가 무엇인지 dashboard 로 확인할 수 있다.
management:
tracing:
sampling:
probability: 1.0
propagation:
type: b3
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
logging:
pattern:
level: "%5p [%X{traceId:-},%X{spanId:-}]"
spring:
cloud:
openfeign:
micrometer:
enabled: true
서버를 기동하고 POSTMAN 으로 주문 , 주문확인의 로직을 거치면 TracdID 와 SpanID 가 정상적으로 나오는 것을 확인할 수 있다.