• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

Circuit Breaker의 적용처 판단

23.11.26 22:37 작성 조회수 179

1

Foo님 안녕하세요.

'섹션3 - 어떤 예외를 recordExceptions로 지정할까?'를 수강하던 중 궁금증이 생겨 질문드립니다.

<서론>

recordExceptions은 '실패라고 간주하여 시스템을 회복시키기 위해 트래픽을 차단할 필요가 있는 상황'에 던져지는 예외로 이해했습니다.

그래서 어떤 상황에서 recordExceptions을 적용해야 할지가 매우 중요할 거라고 생각이 듭니다.

즉 트래픽을 차단할 필요가 있다면 recordExceptions을 던져야 하고 그렇지 않다면 던지지 않아야 할 것입니다.

보통은 트래픽이 많이 몰려서 예외가 발생될 때(ex OutOfMemoryError, RejectedExecutionException) recordExceptions를 적용할 거라고 생각됩니다.

<본론>

그런데 트래픽이 많이 몰리지 않을 때에도 recordExceptions를 적용해야 하는 경우가 있을 것 같습니다. 한번 오류가 발생한 api 호출은 그 이후에 여러 번 호출해도 똑같은 오류가 발생될 가능성이 매우 높을 것 같기 때문입니다. (트래픽이 별로 없는 상황에서도)

그렇다면.. '모든' 외부 api 호출들에 recordExceptions를 다 적용해야 하는 건가? 라는 궁금증이 듭니다. 혹은, 생각을 반대로 전환해서, recordExceptions를 적용하지 않아도 되는 api 호출들을 구분해야 하고 나머지는 모두 recordExceptions를 적용하는 것이 맞는 건가? 라는 생각도 듭니다.

 

즉 어떤 기준으로 recordExceptions를 적용해야 가장 적절한 건지 궁금합니다.

답변 2

·

답변을 작성해보세요.

1

답변은 대댓글 참고해주세요 (_ _)

1

김찬님의 프로필

김찬

질문자

2023.11.26

생각해보니, 특정 유저에 대해서는 api 호출이 계속 에러가 날 테지만 모든 유저에 대해서는 그렇지 않겠네요. 자문자답으로 해결됐습니다!

헛 ㅋ 궁금하신 포인트는 답을 찾으신 것 같은데, 첨언을 좀 드리고 싶어요.

 

일단 recordExceptions로 지정하는 예외들은 '데이터 자체가 문제인 경우' 발생하는 예외들은 지정하면 안됩니다. 말씀하신 것처럼 API 호출량이 적더라도(시스템의 부하가 크지 않더라도) 특정 유저가 잘못된 데이터를 계속 호출하는 경우, 그런건 recordExceptions로 잡으면 안됩니다. 이건 그냥 데이터가 잘못된거지 시스템으로 들어오는 트래픽을 차단한다고 해결되는 문제가 아니니까요.

일반적으로 recordExceptions로 적용하기 가장 적절한 예외들은, 실제로 시스템이 강한 부하를 받았을 때 던져지는 예외들입니다. 대표적으로 애플리케이션이 다른 API 서버를 호출했는데 지속적으로 Timeout이 발생한다면 이 Timeout이 발생할 때 던져지는 예외를 recordExceptions으로 지정하는걸 고려해볼 수 있겠죠. 내 애플리케이션이 호출하고 있는 API 서버 역시 많은 부하를 받고 있기 때문에 Timeout이 발생하고 있을 가능성이 높으니까요. 그럼 해당 서버로 보내는 요청을 차단하여, 내 API에서는 대체 기능(fallback)을 실행시켜줄 수 있고, 문제가 되고 있는 API 서버는 트래픽이 차단되어, 시스템이 회복할 수 있는 시간을 벌어줄 수 있을겁니다.

 

제 경험상 부하가 높아지면 정말 다양한 예외들이 던져집니다. 위에서 이야기한 타임아웃 관련된 것도 있고, 데이터베이스 커넥션 관련 문제 기타 등등 여러가지 예외가 던져집니다. 이런 예외들을 모두 recordExceptions로 한번에 등록하는건 거의 불가능한 일입니다. 따라서, 서비스를 오픈하기 전에 충분히 성능 테스트를 해보면서 높은 부하를 받는 상황에서 어떤 예외들이 던져지는지 뽑아보고, 해당 예외들을 recordExceptions로 지정했을 때 효과적인지 판단해봐야합니다.

 

그리고 너무 일반적인 예외를 recordExceptions로 지정하는 것도 지양해야합니다. 예를들어 RuntimeException 같은걸 recordExceptions로 지정했다면 어떤 일이 생길까요? RuntimeException을 recordExceptions로 지정하면, RuntimeException의 모든 자식 예외들도 recordExceptions로 카운팅이 될겁니다. 근데 RuntimeException의 자식 예외는 엄청나게 많고, 서킷 브레이커의 동작이 필요하지 않은 예외들이 대부분일겁니다. 그럼 의도치 않게 서킷이 계속 열릴거고 시스템은 불필요하게 서킷이 열린 상태를 계속 유지하겠죠. 그럼 서킷 브레이커를 도입한 의미가 없어질겁니다.

 

궁금하신건 해결되셨다고 했지만, 좋은 질문을 해주셔서 추가 답변 남겨봅니다~

또 궁금한 내용 있으면 질문주세요 🙂

감사합니다.