1. 지연 중인 의존 호출이 자원을 점유하는 방식

원격 의존 서비스가 느리거나 응답하지 않으면 호출자는 시간 제한이 끝날 때까지 스레드나 연결을 점유할 수 있습니다. 동시 호출이 쌓이면 같은 자원을 쓰는 다른 작업도 영향을 받을 수 있습니다. 서킷 브레이커는 관측한 실패가 설정 기준에 도달했을 때 추가 호출을 잠시 거부해 대기와 재시도 부하를 줄이는 한 가지 수단입니다. 영향 범위와 회복 결과는 호출 구조와 정책에 따라 달라집니다. 단일 하위 서비스의 장애가 전체 시스템을 반드시 마비시킨다고 일반화하지 마세요.

전선이 이어진 스위치, 끊어진 전선 사이의 스위치, 불꽃이 튀는 스위치를 나란히 그린 개념 일러스트

전기 차단기를 빗댄 그림이며, 특정 소프트웨어 라이브러리의 실제 상태 전이나 정책을 나타내지 않습니다.

2. 서킷 브레이커의 3단계 상태 머신: Closed, Open, Half-Open 전이 원리

서킷 브레이커는 반복되는 의존성 장애를 감지해 호출을 일시 제한함으로써 호출자와 하위 서비스가 타임아웃·재시도 부하를 계속 떠안는 상황을 줄이는 패턴입니다. Martin Fowler의 2014년 설명은 Michael Nygard의 저서 《Release It!》가 이 패턴을 널리 알렸다고 언급하며, Fowler 자신의 글은 한 가지 간단한 구현 예입니다. Closed·Open·Half-Open 세 상태는 널리 쓰이는 모델이지 모든 라이브러리의 불변 규격은 아닙니다. 정상 상태인 '닫힘(Closed)'에서는 요청을 통과시킵니다. 실패 횟수나 비율을 어떤 구간과 오류 기준으로 집계하는지는 구현별 정책에 따라 달라집니다.

3. 실패율 계산 윈도우와 시간 초과(Timeout) 및 회복 유예 시간(Reset Timeout)

임계값을 정하는 방식은 제품과 호출 특성에 따라 다릅니다. Fowler의 단순한 Ruby 예제는 실패율 50%가 아니라 Timeout::Error 횟수를 세며, 기준값 5에 도달하면 회로를 열고 성공 호출이 오면 카운터를 0으로 되돌립니다. 글 뒷부분의 50%는 더 정교한 대안으로 별도 제시됩니다. 어느 값도 권장 기본값은 아닙니다. Microsoft 역시 관찰 구간 내 실패 기준을 설명할 뿐, 모든 제품에 통용되는 기간이나 표본 수를 정하지 않습니다. 고정·이동 창, 최소 표본, 지연 기준, 집계할 오류 종류를 실제 트래픽에 맞춰 정해야 합니다. 업무상 정상 거절이나 잘못된 입력을 장애로 세지 않도록 분리하세요.

가상 정책을 적용해 판정 과정을 살펴보겠습니다. 이 정책이 “판정 대상 호출이 10건 이상일 때 50% 기준을 평가하고, 정상적인 업무 거절은 제외한다”고 정했다고 가정합니다. 9건 중 5건이 실패해도 최소 표본에 못 미치므로 회로를 열지 않고 더 관찰합니다. 판정 대상 10건 중 타임아웃 5건과 성공 5건이면 이 정책은 회로를 엽니다. 이는 임의의 판정 예일 뿐 권장 설정이 아니며, 실제 라이브러리가 최소 표본과 오류 제외를 지원하는지도 확인해야 합니다.

재시도와 서킷 브레이커는 역할이 다릅니다. 재시도는 일시적 실패가 회복될 수 있다고 보고 다시 시도하지만, 브레이커는 반복 실패가 이어질 때 호출을 막습니다. 함께 쓸 때는 브레이커가 비일시적 장애라고 판단해 열렸다는 응답을 재시도 루프가 계속 반복하지 않도록 연결해야 합니다. 그렇지 않으면 회로가 부하를 줄이려는 동안 호출자는 같은 작업을 다시 쌓아 장애를 증폭할 수 있습니다.

브레이커가 열린 뒤의 빠른 실패만큼 보호 호출의 자체 시간 제한도 중요합니다. 원격 호출의 제한 시간이 지나치게 길면 임계값에 도달하기 전 여러 요청이 스레드나 연결을 오래 점유할 수 있습니다. Microsoft와 Fowler는 타임아웃 대기 자체가 자원을 묶어 연쇄 장애로 이어질 수 있음을 지적합니다. 따라서 호출 시간 제한과 실패 집계가 실제 자원 예산 안에서 함께 작동하는지 확인해야 합니다.

4. 차단 뒤 응답과 장애 범위를 정하는 운영 판단

운영에서는 차단기 자체뿐 아니라 차단 뒤의 응답 계약도 미리 정합니다. 읽기 요청에 오래된 데이터를 명시해 내보낼 수 있는지, 안전한 쓰기를 대기열에 넣을 수 있는지, 실패를 반환해야 하는지를 작업별로 구분합니다. Half-Open은 복구 중인 의존성에 제한된 시험 호출만 보내 회복 직후 요청이 한꺼번에 몰리는 것을 줄이는 설계 선택입니다. 허용량과 재개방 조건은 구현에 따라 달라질 수 있습니다.

상태 전이를 기록하고 성공·실패 신호를 관찰하면 임계값이 실제 의존성 상태를 반영하는지 살펴볼 수 있습니다. 복수의 독립 샤드나 공급자가 있는 시스템에서는 하나의 브레이커가 정상 리소스까지 막지 않도록 장애 경계를 분리할 필요가 있습니다. 여러 인스턴스 사이의 상태 공유도 필수 규격이 아니라 일관성 요구와 지연·가용성 비용을 비교할 아키텍처 선택입니다. 예를 들어 서로 독립된 데이터 샤드의 실패를 하나의 카운터로 합치면 한 샤드의 장애가 정상 샤드 호출까지 막을 수 있습니다. 장애 신호를 묶는 단위는 실제 의존성 경계와 맞춰야 합니다.

참고 자료