📌 서킷 브레이커
`서킷 브레이커`란 MSA 간 호출 실패를 감지하고 시스템의 전체적인 안정성을 유지하는 패턴이다.
외부 서비스 호출 실패 시 장애를 격리하고, 시스템의 다른 부분에 영향을 주지 않도록 한다.
상태 변화는 Closed -> Open -> Half Open 순으로 변화한다.
📌 Resilience4j
`Resilience4j`는 서킷 브레이커 라이브러리이다.
다양한 서킷 브레이커 기능을 제공한다!
`Fallback` 메서드를 통해 호출 실패 시 대체 로직을 제공하여 시스템 안정성을 확보한다.
또한 서킷 브레이커 상태를 모니터링하고 관리할 수 있는 다양한 모니터링 도구를 제공한다.
`Resilience4j`를 사용하려면 gradle 의존성을 추가해야 한다.
dependencies {
implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
그리고 `application.yml` 파일에서 관련 설정을 추가하거나 변경할 수 있다.
📌 Fallback 메커니즘
`Fallback` 메서드 정의 통해 외부 서비스 호출이 실패했을 시 대체 로직을 수행할 수 있다.
@Service
public class MyService {
@CircuitBreaker(name = "myService", fallbackMethod = "fallbackMethod")
public String myMethod() {
// 외부 서비스 호출
return externalService.call();
}
public String fallbackMethod(Throwable t) {
return "Fallback response";
}
}
이런 식으로 `fallbackMethod`에 실패 시 실행할 메서드 이름을 설정하면 된다.
이를 통해 장애가 발생해도 사용자에게 일정한 응답을 제공하고 다른 서비스에 장애가 전파되는 것을 막을 수 있다.
spring:
application:
name: my-service
cloud:
circuitbreaker:
resilience4j:
enabled: true
`Resilience4j`는 `Spring Cloud` 패키지의 일부로 다른 구성 요소와 쉽게 통합할 수 있다.
📌 서킷 브레이커 실습
이번 실습은 상품을 조회할 때 상품 아이디 111을 조회 시 에러를 발생시켜 `fallbackMethod`가 실행되는지 확인한다.
spring:
application:
name: sample
server:
port: 19090
resilience4j:
circuitbreaker:
configs:
default: # 기본 구성 이름
registerHealthIndicator: true # 애플리케이션의 헬스 체크에 서킷 브레이커 상태를 추가하여 모니터링 가능
# 서킷 브레이커가 동작할 때 사용할 슬라이딩 윈도우의 타입을 설정
# COUNT_BASED: 마지막 N번의 호출 결과를 기반으로 상태를 결정
# TIME_BASED: 마지막 N초 동안의 호출 결과를 기반으로 상태를 결정
slidingWindowType: COUNT_BASED # 슬라이딩 윈도우의 타입을 호출 수 기반(COUNT_BASED)으로 설정
# 슬라이딩 윈도우의 크기를 설정
# COUNT_BASED일 경우: 최근 N번의 호출을 저장
# TIME_BASED일 경우: 최근 N초 동안의 호출을 저장
slidingWindowSize: 5 # 슬라이딩 윈도우의 크기를 5번의 호출로 설정
minimumNumberOfCalls: 5 # 서킷 브레이커가 동작하기 위해 필요한 최소한의 호출 수를 5로 설정
slowCallRateThreshold: 100 # 느린 호출의 비율이 이 임계값(100%)을 초과하면 서킷 브레이커가 동작
slowCallDurationThreshold: 60000 # 느린 호출의 기준 시간(밀리초)으로, 60초 이상 걸리면 느린 호출로 간주
failureRateThreshold: 50 # 실패율이 이 임계값(50%)을 초과하면 서킷 브레이커가 동작
permittedNumberOfCallsInHalfOpenState: 3 # 서킷 브레이커가 Half-open 상태에서 허용하는 최대 호출 수를 3으로 설정
# 서킷 브레이커가 Open 상태에서 Half-open 상태로 전환되기 전에 기다리는 시간
waitDurationInOpenState: 20s # Open 상태에서 Half-open 상태로 전환되기 전에 대기하는 시간을 20초로 설정
management:
endpoints:
web:
exposure:
include: prometheus
prometheus:
metrics:
export:
enabled: true
`application.yml`
실패율이 50 프로가 넘어가면 서킷 브레이커가 동작한다.
서킷브레이커가 Open 상태가 되면 기존 메서드 대신 `Fallback` 메서드가 실행된다.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class ProductService {
private final Logger log = LoggerFactory.getLogger(getClass());
private final CircuitBreakerRegistry circuitBreakerRegistry;
@CircuitBreaker(name = "productService", fallbackMethod = "fallbackGetProductDetails")
public Product getProductDetails(String productId) {
if ("111".equals(productId)) {
throw new RuntimeException("Empty response body");
}
return new Product(
productId,
"Sample Product"
);
}
public Product fallbackGetProductDetails(String productId, Throwable t) {
return new Product(
productId,
"Fallback Product"
);
}
}
`fallbackGetProductDetails`는 `getProductDetails` 메서드가 실패할 때 호출된다. 해당 메서드는 안전한 대체 로직을 제공한다.
/products/111 을 3번 호출하면 서킷브레이커의 상태가 변경되는 것과 정상적으로 `Fallback` 메서드로 지정된 메서드가 실행되는 것을 알 수 있다.
'공부 > Spring' 카테고리의 다른 글
[Spring Cloud] Gateway PreFilter에 로그인 추가하기 (OAuth2 + JWT) (0) | 2024.08.05 |
---|---|
[Spring Cloud] API Gateway (Spring Cloud Gateway) (0) | 2024.08.05 |
[Spring Cloud] 클라이언트 사이드 로드 밸런싱 (FeignClient와 Ribbon) (0) | 2024.08.05 |
[Spring Cloud] MSA Spring Cloud (Eureka) (0) | 2024.08.01 |
Spring Framework 각 계층의 역할 / 비즈니스 로직은 누구의 역할일까? (0) | 2024.07.08 |