─━ IT ━─

"옆 서비스가 죽었는데, 왜 우리까지?" 😭 연쇄 장애를 막는 안전장치, 서킷 브레이커 패턴 (Circuit Breaker Pattern)

DKel 2025. 9. 21. 22:43
반응형

마이크로서비스 아키텍처에서 '주문 서비스'가 '결제 서비스'를 호출하는, 흔한 상황을 가정해 봅시다. 어느 날, '결제 서비스'에 갑자기 장애가 발생해 응답이 오지 않습니다. 이때 '주문 서비스'는 어떻게 될까요? '결제 서비스'의 응답을 하염없이 기다리다가, 결국 대기 중인 요청(Request)들이 계속 쌓이게 됩니다. 얼마 지나지 않아 '주문 서비스'마저 리소스 고갈로 다운되고, 이어서 '주문 서비스'를 호출하던 다른 서비스들까지 차례로 무너지는 연쇄 장애(Cascading Failures) 가 발생합니다. domino effect

이런 대참사를 막기 위해, 똑똑한 개발자들은 실제 세계의 전기 공학에서 힌트를 얻었습니다. 바로 서킷 브레이커(Circuit Breaker), 즉 '회로 차단기'입니다.


서킷 브레이커 패턴이란? 더 큰 고장을 막는 자동 차단기

서킷 브레이커 패턴은 특정 서비스에 대한 호출이 계속 실패하면, 추가적인 호출 시도가 아예 실패할 것이라고 가정하고 즉시 요청을 차단하는 디자인 패턴입니다. 문제가 생긴 서비스를 불필요하게 계속 호출하여 자원을 낭비하는 대신, "저 서비스는 지금 아프니, 잠시 쉬게 해주자"고 판단하고 스스로 연결을 끊어버리는 것이죠.

이름처럼, 가정집의 두꺼비집(회로 차단기) 과 똑같이 작동합니다.

  • 정상 상황: 전기가 원활하게 흐릅니다. (요청이 정상적으로 전달됨)
  • 과부하 발생: 특정 전기 기구에 문제가 생겨 과전류가 흐르면, 차단기가 "철컥!"하고 내려가며 전기 공급을 끊습니다. 이는 더 큰 화재나 다른 가전제품의 고장을 막기 위함입니다.
  • 상태 확인: 잠시 후, 우리는 차단기를 다시 올려보며 "이제 괜찮나?" 하고 확인합니다.

소프트웨어의 서킷 브레이커는 이 과정을 세 가지 상태(State)로 관리합니다.

  1. 닫힘 (Closed): 평소의 정상 상태입니다. 모든 요청은 정상적으로 대상 서비스로 전달됩니다. 하지만 실패 횟수를 조용히 세고 있습니다. 실패율이 정해진 임계값(e.g., 최근 1분간 50% 이상 실패)을 넘어서면, 차단기는 '열림' 상태로 전환됩니다. 🟢
  2. 열림 (Open): 차단기가 내려간 상태입니다. 이 상태에서는 대상 서비스로 가는 모든 요청을 즉시 차단하고, 곧바로 에러를 반환합니다. "지금 저 서비스는 아프니까, 나중에 다시 시도해"라는 빠른 실패(Fail Fast)를 응답하는 것이죠. 이는 우리 시스템이 불필요한 대기 시간으로 고통받는 것을 막아줍니다. 정해진 시간이 지나면(e.g., 30초 후), 차단기는 '반-열림' 상태로 넘어갑니다. 🔴
  3. 반-열림 (Half-Open): 차단기를 살짝 다시 올려보는, 테스트 상태입니다. 제한된 수의 테스트 요청(e.g., 단 한 개의 요청)만 대상 서비스로 보내봅니다.
    • 성공하면? "아, 이제 서비스가 회복되었구나!"라고 판단하고, 차단기는 다시 '닫힘' 상태로 돌아가 모든 요청을 정상 처리합니다.
    • 실패하면? "아직 회복이 안 됐군."이라고 판단하고, 다시 '열림' 상태로 돌아가 대기 시간을 갖습니다. 🟡

왜 이것이 필수적일까요?

서킷 브레이커는 단순히 하나의 서비스 장애가 시스템 전체의 붕괴로 이어지는 것을 막는 것 이상의 이점을 제공합니다.

  • 빠른 실패 (Fail Fast): 사용자는 서비스가 '먹통'이 되어 무한정 기다리는 최악의 경험 대신, "잠시 후 다시 시도해주세요"라는 명확하고 빠른 피드백을 받게 됩니다.
  • 장애 서비스의 회복 기회: 문제가 생긴 서비스는 더 이상 새로운 요청의 홍수에 시달리지 않고, 스스로를 복구할 수 있는 귀중한 시간을 벌게 됩니다.
  • 시스템 탄력성 (Resilience) 증대: 일부 서비스가 불안정하더라도, 시스템의 다른 건강한 부분들은 계속 정상적으로 동작할 수 있도록 격리시켜 줍니다.

마치며

서킷 브레이커 패턴은 "모든 것은 언젠가 실패한다(Everything fails, all the time)"는 사실을 인정하고, 그 실패가 미치는 영향을 최소화하려는 성숙한 엔지니어링의 산물입니다. 각 서비스 앞에 똑똑한 자동 차단기를 하나씩 두는 것만으로도, 우리 시스템의 안정성과 회복탄력성은 몇 단계나 상승할 수 있습니다.

내 서비스가 다른 서비스의 장애 때문에 억울하게 죽는 일을 막고 싶다면, 서킷 브레이커는 당신의 코드에 반드시 필요한 안전벨트가 되어줄 것입니다. ⛑️

반응형