Post

서킷브레이커로 LLM 공급자 장애 자동 우회하기

LLM 공급자 장애를 CLOSED·OPEN·HALF_OPEN 상태 머신으로 감지하고 다음 공급자로 자동 전환하는 서킷브레이커를 구현했다

서킷브레이커로 LLM 공급자 장애 자동 우회하기

서킷브레이커로 LLM 공급자 장애 자동 우회하기

공급자가 간헐적으로 503을 내는데 매번 수동으로 다른 공급자로 바꿔야 했다. 연속 실패를 감지해 자동으로 우회하는 서킷브레이커를 붙였다.

1. 서론 (Introduction)

  • 문제/상황 (Problem): LLM 공급자가 간헐적으로 장애를 낸다. 실패가 반복되는 동안 계속 같은 공급자로 요청을 보내면 불필요한 대기 시간이 쌓인다.
  • 목적 (Purpose): 연속 실패가 임계치를 넘으면 공급자를 일시 차단하고, 일정 시간 후 자동으로 복구를 시도하는 서킷브레이커를 구현한다.
  • 대상 (Target Audience): LLM 공급자 장애에 대응하는 자동 복구 구조가 필요한 개발자.

2. 방법 및 과정 (Methods & Process)

  • 배경 조사 및 데이터 (Data Collection): 공급자 하나가 장애일 때 상태별 동작을 정리했다.

    상태요청 처리전이 조건
    CLOSED정상 전달연속 실패 threshold 도달 시 OPEN
    OPEN즉시 차단, 폴백recovery_timeout 경과 시 HALF_OPEN
    HALF_OPEN프로브 1건만 허용성공 시 CLOSED, 실패 시 다시 OPEN
  • 접근 방법 (Approach Methods):
    • [방법 1] 3상태 머신: CLOSED/OPEN/HALF_OPEN 세 상태를 두고 실패 카운터와 마지막 실패 시각으로 전이 조건을 판단한다.
    • [방법 2] 우선순위 폴백: 공급자 우선순위 리스트를 순회하며 서킷이 열려있지 않은 첫 번째 공급자로 요청을 보낸다. 실패하면 해당 공급자의 서킷 상태만 갱신하고 다음 순위로 넘어간다.
  • 분석 및 해결 프로세스 (Analysis Flow):
    • 도구/기술: Python 클래스 기반 상태 머신, time.time() 기반 recovery_timeout 판정.
    • 주요 단계: 요청 전 is_available() 확인 $\rightarrow$ OPEN이면 스킵·다음 공급자 $\rightarrow$ 성공/실패에 따라 report_success/report_failure 호출 $\rightarrow$ threshold 초과 시 OPEN 전이, recovery_timeout 경과 시 HALF_OPEN 전이.
    • 결과 도출 및 검증: threshold 3, recovery_timeout 5초로 두고 한 공급자를 항상 실패하도록 설정했다. 3회 연속 실패 후 해당 공급자 서킷이 OPEN으로 전환되고, 이후 요청은 그 공급자를 건너뛰고 우선순위상 다음 공급자로 즉시 전달됐다. 시각을 recovery_timeout 이후로 이동시키면 HALF_OPEN으로 전이됐고, 프로브 성공 처리 후 CLOSED로 복귀했다.

3. 결과 (Results)

  • 분석 결과 요약: 장애 공급자는 3회 실패 후 자동으로 격리됐고 이후 요청은 대기 없이 다음 우선순위 공급자로 넘어갔다. OPEN 상태에서는 장애 공급자로의 실제 호출 자체가 발생하지 않아 타임아웃 대기가 없었다. recovery_timeout 경과 후 프로브가 성공하면 별도 조치 없이 CLOSED로 복귀했다.

4. 인사이트 및 액션 (Insights & Action)

  • 인사이트 (Insight): 서킷브레이커는 장애를 숨기지 않는다. 장애를 빠르게 감지해 대피로를 여는 것이다. 전체 시스템은 계속 동작하고 장애 공급자만 격리된다.
  • 실행 방안 (Action Plan): 서킷 상태 변화를 로깅해두면 공급자별 안정성을 사후에 분석할 수 있다. OPEN 빈도가 높은 공급자는 우선순위를 낮추는 근거로 쓴다.
  • 한 줄 결론 (Key Takeaway): 서킷브레이커 하나로 공급자 장애가 전체 서비스 장애로 번지는 걸 막을 수 있다. 샘플 코드
  • 다음 스텝 (Next Step): 지금 구현은 프로세스 하나의 메모리 상태로만 동작한다. 워커가 여러 개인 환경에서는 각 워커가 서킷 상태를 따로 들고 있어 한쪽에서 OPEN으로 판단해도 다른 워커는 계속 장애 공급자로 요청을 보낸다. 상태를 외부 저장소로 공유하는 구조가 필요하다.
This post is licensed under CC BY 4.0 by the author.