서킷 브레이커

Code_Builder·2024년 8월 1일
0
post-thumbnail

서킷브레이커란?

외부서비스에서 호출 실패(장애 발생)시, 실패가 발생한 시점이후로 부터 정지시켜 다른 시스템에 영향을 주지 않도록하는 것

출처: https://qwer9412.tistory.com/2


  • 상태:
    • 클로즈드: 모든 요청이 정상
    • 오픈: 호출 실패 임계치 도달로 인해 외부 서비스에 대한 호출이 차단
    • 하프 오픈: 일부 요청이 외부 서비스에 전달되며, 서비스가 복구되었는지 테스트하는 역할

Resilience4j

서킷브레이커 라이브러리 중 하나로 서비스 간의 호출 실패를 감지하고 시스템의 안정성을 유지

  • 특징
    • 위에서 말한 상태로 호출 실패를 관리
    • 호출 실패 시 대체 로직을 제공하여 시스템 안정성 확보하는 Fallback
    • 모니터링 및 관리 할 수있는 도구 제공

사용하는 의존성: io.github.resilience4j:resilience4j-spring-boot3:2.2.0


Resilience4j와 Spring Cloud 연동 실습

  • Prouct.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {

    private String id;
    private String title;

}
  • ProductController.java
@RestController
@RequiredArgsConstructor
public class ProductController {

    private final ProductService productService;


    @GetMapping("/product/{id}")
    public Product getProduct(@PathVariable("id") String id) {
        return productService.getProductDetails(id);
    }
}
  • ProductService.java
@Service
@RequiredArgsConstructor
public class ProductService {

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final CircuitBreakerRegistry circuitBreakerRegistry;

    @PostConstruct
    public void registerEventListener() {
        circuitBreakerRegistry.circuitBreaker("productService").getEventPublisher()
            .onStateTransition(event -> log.info("#######CircuitBreaker State Transition: {}", event)) // 상태 전환 이벤트 리스너
            .onFailureRateExceeded(event -> log.info("#######CircuitBreaker Failure Rate Exceeded: {}", event)) // 실패율 초과 이벤트 리스너
            .onCallNotPermitted(event -> log.info("#######CircuitBreaker Call Not Permitted: {}", event)) // 호출 차단 이벤트 리스너
            .onError(event -> log.info("#######CircuitBreaker Error: {}", event)); // 오류 발생 이벤트 리스너
    }


    @CircuitBreaker(name = "productService", fallbackMethod = "fallbackGetProductDetails")
    public Product getProductDetails(String productId) {
        log.info("###Fetching product details for productId: {}", productId);
        if ("111".equals(productId)) {
            log.warn("###Received empty body for productId: {}", productId);
            throw new RuntimeException("Empty response body");
        }
        return new Product(
            productId,
            "Sample Product"
        );
    }

    public Product fallbackGetProductDetails(String productId, Throwable t) {
        log.error("####Fallback triggered for productId: {} due to: {}", productId, t.getMessage());
        return new Product(
            productId,
            "Fallback Product"
        );
    }
 }
  • 결과

성공

실패

profile
사소한일에도 최선을 다하기

0개의 댓글

관련 채용 정보