현재 맡고 있는 서비스는 정부전자문서지갑 API에 대한 의존도가 높은데, 이 API는 장애가 잦은 편이다.
장애가 발생하면 서비스 응답 속도가 느려지고, 결국 사용자 경험이 나빠진다.
이런 문제를 해결하기 위해 Circuit Breaker 적용을 좀 더 세분화하여 진행했다.
기존에는 큰 기능 단위로만 Client Bean을 나누었지만, API 특성별로 더 세분화하여 대응하기로 했다.
일반적으로 외부 API를 호출하는 Client Bean은 host 단위로 생성한다. 하지만 장애가 잦은 API에 대해 더 정밀한 대응이 필요했기에, 장애 유형별, 구간별로 Client Bean을 추가 분리했다. 분리된 client들은 서로 중복으로 api path를 가질 수 있으며, 각 client 객체는 호출되는 시점이 다르다.
기존 구조 (AS-IS)
개선된 구조 (TO-BE)
장애가 자주 발생하는 api별 client bean 생성
점검 유형 정하기 위한 구간별 client bean
서비스 특성상 read timeout이 15초로 설정되어 있었고, 정부전자문서지갑 서버는 Timeout 에러가 자주 발생하는 상태였다.
Circuit Breaker가 오픈되면서
Client Bean을 세분화하면서
Circuit Breaker는 각 파드에서의 에러율을 기준으로 동작하기 때문에,
트래픽 대비 Pod 수가 많으면 서킷이 제대로 동작하지 않는 문제가 있다.
현재 트래픽에 비해 설정된 Pod 수가 많았고, 적절한 Pod 개수로 조정하여 서킷이 정상적으로 동작할 수 있도록 했다.
Resilience4j의 Circuit Breaker는 아래 2가지 Sliding Window 방식을 지원한다. 참고
Count-based Sliding Window
Time-based Sliding Window
처음에는 Time-based 방식을 고려했지만, Client Bean 세분화 및 낮은 트래픽을 가진 서비스의 특성을 고려하여 Count-based로 결정했다.
서비스를 차단한 경우, 예외를 발생시키는 대신 미리 준비된 동작을 실행하는 것을 의미한다.
즉, Circuit Breaker가 Open 상태일 때 요청을 에러로 응답하지 않고, 대체 응답을 제공하는 방식이다.
이번 작업의 목표는 빠르게 에러를 감지하고 사용자에게 안내하는 것이었기 때문에, Fallback을 적용하지 않고 즉시 에러 안내 페이지를 노출하도록 했다.