Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

서킷 브레이커 패턴

대부분의 소프트웨어들은 다른 프로세스를 호출하기 마련이다. 내부에 있는 프로세스를 (IPC를 이용해서) 호출하는 경우도 있겠지만, 특히 MSA, OpenAPI가 일반화된 요즘에는 다른 네트워크에서 실행 중인 프로세스 원격으로 호출하는 경우가 많다.

IPC 통신과 원격 통신하는 소프트웨어의 가장 큰 차이점은 "상황을 완전히 통제 할 수 없다는 점"이다. 요청이 도달하지 않거나, 제한시간내에 응답이 없는 경우 원격 통신 소프트웨어는 할 수 있는게 없다. MSA의 경우 하나의 프로세스에 문제가 생길 경우, 연속적으로 다른 프로세스에 영향을(cascading failures) 줄 수 있다.

A->B->C->D 이렇게 호출하는 서비스가 있다고 가정해보자. "D"가 응답을 받지 못하면, A, B, C가 연속으로 에러를 발생할 것이다. 이런 오류가 발생할 경우 응답을 받지 못한 프로세스는 timeout 시간동안 자원을 잠유하기 때문에 리소스 관리에 문제가 생기고, 문제가 전체 시스템에 전파되게 된다. 이런 오류는 연속된 다른 프로세스 모두에서 발생 하기 때문에 문제가 걷잡을 수 없이 커지게 된다.

이런 재앙을 회피하기 위해서 고안안 패턴이 "서킷 브레이커 패턴(Circut Breaker Pattern)"이다.

아이디어는 간단하다. "특정 프로세스에 문제가 생기면(임계치를 초과하게 되면) 차단기가 닥동을 해서 해당 프로세스를 호출하는 모든 요청을 취소하고 즉시 오류를 반환한다." 아이디어의 구현을 위해서 아래와 같은 룰을 만들 수 있을 거다.
  • 특정 API 요청이 3번 연속 실패할 경우 요청을 차단한다.
  • 특정 API 오청이 5번 연속 n초 이상 시간을 초과 할 경우 요청을 차단한다.
  • 요청을 차단했던 API가 3번 연속 성공 할 경우 요청을 전송한다.
이러한 작업을 위해서는 모니터링 시스템이 필수다. 아래 그림은 서킷 브레이커 작동 방식을 묘사하고 있다.

 Circuit breaker 패턴 작동방식

실패를 포용한다.

애플리케이션 디자인의 최근 핵심은 "실패가 발생하는 것을 상수"로 둔다는 것이다. 애플리케이션이 클라우드위에 올라가고 유연성과 배포속도를 중요시하게 되면서, 인스턴스, 네트워크, 메시지 큐, 인증/권한등을 외부로 위임 하고 이들을 다시 통합하는 모델을 사용하고 있다. 애플리케이션이 느슨하게 연결된 소프트웨어 군단의 일원이 되면서, 실패를 막는 것이 불가능해졌다. 이제 개발자들은 다양한 방식으로 애플리케이션이 실패 할 수 있다는 것을 가정하고 있다.

일종의 안정성,유연성,관리성 간의 트레이드오프(Tradeoff)라고 할 수 있겠다. 물론 유연성을 더 중요하시는게 지금 추세다. 서킷 브레이커 패턴은 유연성과 속도를 유지하면서 실패를 줄이고, 실패의 효과를 완하해서 서비스의 복원력을 높이는데 도움을 준다.

실패를 포용한다고 해서, 실패를 신경쓰지 않는 다는 것이 아니다. 서킷 브레이커 패턴의 가장 중요한 목표중 하나는 "실패를 방지"하는 것이다. 예를 들어서 메모리와 CPU, Disk 부족과 같은 일부 오류들은 문제가 발생하기 전에 인식하고 이를 방지하기 위한 조치를 취할 수 있다. 서킷 브레이커는 이러한 징후를 발견하면, 시스템이 비정상임을 알리고 요청수를 제한하거나 인스턴스를 늘리거나 라우팅을 새로 하는 것으로 서비스를 복구 할 수 있는 기회를 제공한다.

개발자들은 문제가 발생 혹은 확산되기 전에 원인을 찾아서 해결하고, 서비스 정책을 원래대로 하는식으로 전체 서비스의 건강을 크게 해치지 않으면서 서비스를 지속 할 수 있다.

Envoy, Nginx, Traefik 등의 프락시들이 서킷 브레이커를 지원한다.

서킷 브레이커 States

 서킷 브레이커 상태

서킷 브레이커는 3개의 주요 상태를 가진다.
  • Closed : 요청에 대한 기본 상태다. 요청이 특정 임계치 값 아래에서 성공 혹은 실패 할 경우 상태는 동일하게 유지된다. 측정 가능한 오류는 Max Concurrency 와 Timeout 이다.
  • Open : Circuirt Open이 된다. 모든 요청은 오류로 표시된다. 타임아웃을 기다리지 않고 즉시 실패(fail fast)한다.
  • HalfOpen : 주기적으로 시스템이 복구가 됐는지 확인한다. 이 경우 서킷 브레이커가 Closed 상태로 전환하거나 Open 상태를 유지한다.

서킷 브레이커 이론

서킷 브레이커는 5개의 주요 파라메터를 가진다.
type CommandConfig struct {  
    Timeout                int `json:"timeout"`  
    MaxConcurrentRequest   int `json:"max_concurrent_requests"`  
    RequestVolumeThreshold int `json:"request_volume_threshold"`  
    SleepWindow            int `json:"sleep_window"`  
    ErrorPercentThreshold  int `json:"error_percent_threshold"`   
}                                                                             
임계값은 두 서비스 간의 SLA 정책에 따라서 결정될 수 있다. 이러한 값들은 미세조정이 필요하다.

좋은 서킷 브레이커는 서비스 연결에 문제가 있음을 정확히 나타낼 수 있어야 한다. 실제로 하나의 서비스에 연결하기 위한 여러 개의 API 엔드포인트가 있을 수 있다. 각 엔드 포인트 별로 서킷 브레이커를 설치하는 것이 합리적이다.

참고