Circuit Breaker 목적은 무엇일까요?
Circuit Breaker 패턴은 장애가 발생했을 때 장애가 전파되는 것을 막기 위한 패턴입니다.
원래라면, 서비스 A가 서비스 B를 호출하고, 서비스 B가 장애가 발생하면 서비스 A도 장애가 발생합니다.
Circuit Breaker 패턴을 적용하면, 서비스 A가 서비스 B를 호출할 때 더 이상 호출하지 않도록 차단합니다.
차단하는 것을 통해서 서비스 A는 정상적으로 작동할 수 있도록 하는 목적을 가지고 있습니다.
Circuit Breaker 패턴의 구성요소
Circuit Breaker 패턴은 크게 3가지로 구성되어 있습니다.
- Open
- Half Open
- Closed
Open
Open 상태는 Circuit Breaker가 차단되어 있는 상태입니다.
Open 상태에서는 서비스 A가 서비스 B를 호출하지 않습니다.
Half Open
Half Open 상태는 Circuit Breaker가 일정 시간이 지난 후에 서비스 B를 호출할 수 있도록 하는 상태입니다.
Closed
Closed 상태는 Circuit Breaker가 정상적으로 서비스 B를 호출할 수 있는 상태입니다.
정상적인 상황은 Closed 상태라고 생각하시면 됩니다.
Circuit Breaker 구현체
Circuit Breaker 패턴은 크게 3가지로 구현할 수 있습니다.
- Hystrix
- Resilience4j
- Istio(서비스 매쉬라고 많이 불립니다.)
여기서 Istio를 활용한 Circuit Breaker 패턴은 단점이 있습니다.
Host 단위로밖에 Circuit Breaker를 적용할 수 없습니다.
실제 API 개발을 하다 보면 Host는 같고, 엔드포인트만 달라지는 경우가 있을 텐데, 이런 부분에서 한계가 있습니다.
Hystrix의 경우에는 모든 요청이 HystrixxCommand라는 것으로 감싸져야 하기에, 코드가 지저분해집니다. 또한, 현재는 넷플릭스에서 더 이상의 개발을 진행하지 않고 있습니다.
또한 Hystrix의 처리 방식에도 문제가 있습니다. Thread를 활용하는 방식과, Semaphore를 활용하는 방식이 있습니다.
Semaphore을 사용하면 격리성이 떨어지는 문제가 있고, Thread를 활용하면 Thread를 많이 사용하게 되어서, Thread를 관리하는 데에도 부담이 있습니다.
이런 장점이 크기에, Hystrix에서도 Resilience4j 를 사용하기를 권장하고 있습니다. 저도 Resilience4j 를 추천합니다.
Resilience4j
Resilience4j 란?
Resilience4j는 자바 8+ 에서 사용할 수 있는 다양한 기능들을 모아둔 라이브러리입니다.
그 기능 중 하나가 Circuit Breaker입니다.
Resilience4j의 Circuit Breaker
Circuit Breaker의 상태는?
Circuit Breaker의 상태는 크게 일반적인 3가지와 특수한 2가지로 구성되어 있습니다.
위쪽에 설명드린 Open(호출을 못하는 상태), Half Open(호출을 일정 시간이 지난 후에 호출할 수 있는 상태), Closed(정상적으로 호출할 수 있는 상태)가 일반적인 상태입니다.
그리고 특수한 상태로는 Forced Open(강제로 Open 상태로 만드는 상태), Disabled(강제로 Closed 상태로 만드는 상태)가 있습니다.
Circuit Breaker의 상태 전이
Circuit Breaker의 상태 전이는 위와 같습니다.
Closed 상태에서는 호출이 정상적으로 이루어지고, 호출이 정상적으로 이루어지면 Failure Rate 가 증가하지 않습니다.
호출이 실패하면 Failure Rate 가 증가하고, Failure Rate 가 일정 수준을 넘어가면 Open 상태로 전이됩니다.
Open 상태에서는 호출이 차단되고, 일정 시간이 지나면 Half Open 상태로 전이됩니다.
Half Open 상태에서는 호출이 정상적으로 이루어지면 Closed 상태로 전이되고, 호출이 실패하면 Open 상태로 전이됩니다.
임계값을 정할 때는 총 2가지 방식이 있습니다.
- 마지막 N 번의 시도 중 몇 번 실패했는지
- 마지막 N 초동안 얼마나 실패했는지
위의 2가지 방식을 사용할 수 있습니다.
당연하지만, 마지막 N 초동안 얼마나 실패했는지 방식이 더 정확합니다.
여기서 Circuit는 당연하지만, Thread safe 하도록 동작하게 되어있습니다.
여러 스레드가 동시에 호출하더라도, Circuit Breaker는 정상적으로 동작합니다.
긴 글을 읽어주셔서 감사합니다
'프로그래밍 방법' 카테고리의 다른 글
Oauth의 등장 배경과, 변화 과정에 대해 알아보자 (0) | 2023.05.24 |
---|---|
명확한 판단 근거를 만들자(feat: chatgpt) (0) | 2023.03.29 |
GraphQL (0) | 2022.09.22 |
도메인 주도 설계 철저 입문 Domain Driven Design(DDD) - 2 (0) | 2022.09.13 |
도메인 주도 설계 철저 입문 Domain Driven Design(DDD) (2) | 2022.09.09 |