Circuit Breaker(서킷 브레이커) 패턴은 시스템의 장애 전파를 방지하고, 안정성을 유지하기 위한 마이크로서비스 설계 패턴입니다.
1. Circuit Breaker란?
- "회로 차단기"라는 뜻으로, 특정 서비스 호출에 실패하거나 응답 지연이 발생했을 때 추가 호출을 차단하고 빠르게 대체 동작(폴백)을 실행합니다.
- 이를 통해 시스템의 과부하와 전체 장애 전파를 방지합니다.
2. Circuit Breaker의 동작 원리
3가지 상태
Closed (닫힘)
- 정상 상태로, 모든 요청이 허용됩니다.
- 이 상태에서 실패가 기준치를 초과하면 Open 상태로 전환됩니다.
Open (열림)
- 실패가 감지되었을 때 추가 요청을 차단합니다.
- 일정 시간 후 Half-Open 상태로 전환되어 일부 요청을 허용해 봅니다.
Half-Open (반열림)
- 일부 요청을 허용해서 서비스 상태를 확인합니다.
- 성공하면 Closed로 돌아가고, 실패하면 다시 Open 상태로 유지됩니다.
3. Circuit Breaker의 동작 흐름
- Closed 상태에서 서비스 호출이 실패하면 실패 횟수를 기록합니다.
- 실패 횟수나 비율이 임계치(Threshold)를 넘으면 Open 상태로 전환됩니다.
- Open 상태에서는 새로운 요청을 차단하고 폴백(Fallback) 메커니즘을 실행합니다.
- 일정 시간 후 Half-Open 상태로 전환되며, 일부 요청을 테스트로 보내 상태를 확인합니다.
- 테스트 요청이 성공하면 Closed 상태로 돌아가고, 실패하면 Open 상태를 유지합니다.
4. Circuit Breaker의 필요성
✅ 장애 전파 방지: 한 서비스에서 장애가 발생해도 다른 서비스로 퍼지는 것을 막습니다.
✅ 리소스 보호: 실패한 서비스에 대한 과도한 요청을 차단하여 시스템 자원을 보호합니다.
✅ 빠른 오류 감지: 서비스의 상태를 빠르게 감지하고 대체 동작(폴백)을 제공하여 사용자 경험을 유지합니다.
5. Circuit Breaker의 주요 구현 방법
1) Resilience4j를 사용한 Circuit Breaker
Resilience4j는 Java에서 사용되는 가볍고 유연한 서킷 브레이커 라이브러리입니다.
Maven 의존성 추가
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>1.7.1</version>
</dependency>
코드 예제
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import java.time.Duration;
import java.util.function.Supplier;
public class CircuitBreakerExample {
public static void main(String[] args) {
// 서킷 브레이커 설정
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 실패 비율이 50%를 넘으면 Open 상태로 전환
.waitDurationInOpenState(Duration.ofSeconds(5)) // Open 상태 유지 시간
.slidingWindowSize(10) // 실패율을 계산하는 슬라이딩 윈도우 크기
.build();
// 서킷 브레이커 생성
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("example");
// 서킷 브레이커 적용
Supplier<String> decoratedSupplier = CircuitBreaker
.decorateSupplier(circuitBreaker, CircuitBreakerExample::unstableService);
// 요청 실행
for (int i = 0; i < 20; i++) {
try {
String result = decoratedSupplier.get();
System.out.println("요청 성공: " + result);
} catch (Exception e) {
System.out.println("요청 실패: " + e.getMessage());
}
}
}
// 실패할 수 있는 서비스
private static String unstableService() {
if (Math.random() > 0.5) {
throw new RuntimeException("Service Failure");
}
return "Service Success";
}
}
설명
설정:
- 실패 비율이 50%를 초과하면 Open 상태로 전환됩니다.
- 5초 동안 Open 상태를 유지한 후 Half-Open으로 전환됩니다.
- Sliding Window 크기는 최근 10개 요청을 기준으로 실패율을 계산합니다.
동작:
unstableService()
메서드가 랜덤하게 실패하도록 구성했습니다.- 실패율이 높으면 서킷 브레이커가 Open 상태가 되어 새로운 요청을 차단합니다.
6. 서킷 브레이커 패턴과 폴백
서킷 브레이커와 폴백(Fallback) 패턴은 자주 함께 사용됩니다.
- 서킷 브레이커: 장애를 감지하고 요청을 차단
- 폴백: 요청이 차단된 경우 대체 데이터를 반환하거나 다른 처리를 수행
Resilience4j에서 폴백 적용 예시:
Supplier<String> fallback = () -> "대체 응답입니다.";
Supplier<String> decoratedWithFallback = CircuitBreaker
.decorateSupplier(circuitBreaker, CircuitBreakerExample::unstableService)
.andThen(result -> result) // 성공한 경우 그대로 반환
.exceptionally(e -> fallback.get()); // 실패한 경우 폴백 실행
7. 주요 용어 정리
용어 | 설명 |
---|---|
Closed | 정상 상태, 모든 요청 허용 |
Open | 실패율 초과, 요청 차단 |
Half-Open | 일부 요청을 허용하여 상태 확인 |
Failure Rate | 실패 비율 임계치 (예: 50%) |
Wait Duration | Open 상태에서 유지되는 시간 |
Sliding Window | 실패율을 계산하는 기준이 되는 요청 수 |
8. 요약
✅ Circuit Breaker는 장애를 감지하고 시스템의 안정성을 유지하는 패턴입니다.
✅ 3가지 상태: Closed, Open, Half-Open
✅ 주요 기능:
- 장애 감지
- 요청 차단
- 폴백 제공
✅ Resilience4j와 같은 라이브러리를 사용하면 쉽게 구현할 수 있습니다.
이 패턴을 사용하면 마이크로서비스 아키텍처나 외부 서비스 호출 시 발생할 수 있는 장애 전파를 효과적으로 방지할 수 있습니다! 😊
'Microservices Architecture' 카테고리의 다른 글
Netflix Zuul (0) | 2024.12.16 |
---|---|
링 버퍼(Ring Buffer) (0) | 2024.12.13 |
폴백(Fallback) (0) | 2024.12.13 |
엘라스틱서치(Elasticsearch) (0) | 2024.12.10 |
12 팩터 앱(12 Factor App) (0) | 2024.12.10 |