Circuit Breaker가 뭘까?
Circuit Breaker는 회로 차단기입니다. 말 그대로 내리면 정전이 되는 그 회로 차단기를 의미하는 건 아니고, 일종의 비유입니다.
MSA 환경에서는 개별 Application의 복잡도는 내려가지만, 인프라 레벨에서의 복잡도는 늘어납니다. Client에게는 1개의 요청으로 보여도, 그 안에는 여러 MS 끼리 네트워크를 통해 요청을 주고 받습니다. 당연히 이 과정에서 실패 확률이 올라갑니다.
만약, 전기를 내리는 회로 차단기처럼 이런 오류를 방지하는 패턴이 없다면 한 MS의 오류가 다른 MS에게 번지기 때문에 이를 예방하기 위해 Circuit Breaker 패턴을 쓰게 됩니다.
Circuit Breaker의 작동 방법
Circuit Breaker는 지속적으로 상태를 확인하고, 미리 정해둔 설정값 이상으로 에러가 나면 Closed 상태에서 Open 상태로 바뀌게 됩니다. 그럼 미리 정해둔 Fallback을 실행하거나, 에러를 뱉습니다. 일정 시간 뒤에 Half-Open 상태가 되어 일부 요청을 받고, 여기서 문제가 없으면 다시 Closed 상태가 됩니다.
예를들어, 게시글을 불러오는 API가 있고, 여기서 조회수 API에서 오류가 나서 Circuit Breaker가 Open 상태가 됐다고 가정하겠습니다. 조회수는 일반적으로 꼭 항상 정확할 필요는 없기 때문에 Fallback으로 마지막으로 Cache에 있던 값이나, 심지어는 랜덤한 숫자를 빠르게 return 할 수도 있습니다.
Circuit Breaker를 쓰지 않았다면 그다지 핵심은 아닌 조회수 때문에 게시글 API 전체가 응답이 느려지거나, 오류가 났을 겁니다.
Circuit Breaker의 문제점
Circuit Breaker의 핵심은 MS 사이에 장애를 전파시키지 않고 빠르게 Fallback을 가동해서 Downtime을 최소화하는 것입니다.
하지만 1가지 무시할 수 없는 단점이 있습니다. 결국 Circuit Breaker가 Open 되기 전에 응답이 오래 걸리는 API는 Thread를 모두 점유해 버려 그 사이 다른 MS에서 요청을 하면 오류가 난다는 것입니다.
Bulkhead가 해결책!
이를 해결해 주는게 Bulkhead 패턴입니다.
Bulkhead는 특정 요청 단위당 쓸 수 있는 자원을 한정시키는 기술입니다.
Bulkhead로 쓸 수 있는 자원(Resources)을 한정시키면 요청이 많이 와서 Queue에 쌓여도 Thread Pool이나 Connection Pool 같은 서버 자원을 점유하지 않아 Circuit Breaker가 Closed 상태여도 다른 요청은 정상적으로 처리됩니다.
Circuit Breaker, Bulkhead 적용했을 때의 Metric
Thread Pool - currentThreadsBusy 을 주목해 보시면 요청을 엄청 날렸을 때 BusyThread가 1개가 됐다가 Circuit Breaker가 작동되니 0개로 됩니다. (Thread를 사용해서 요청을 처리하는게 아닌 Circuit Breaker가 정해진 Fallback만 하므로)
그 다음으로 요청을 2곳에서 날려도 Bulkhead가 적용되서 Thread는 1개만 점유합니다.
마지막으로 Bulkhead를 푸니 Thread를 모두 (2개) 점유합니다. 이때 만약 다른곳에서 요청을 날리면 Timeout이 오겠죠?
사실 Bulkhead는 많이 쓰이지 않는다...
Circuit Breaker가 열리기 전에 Queue에 요청이 차면 자원을 점유해서 오류가 난다, 그래서 Bulkhead를 써서 자원을 점유하지 못하게 한정시킨다.
이건 잘 알았는데 실제로 Bulkhead가 잘 쓰일까요? 사실은 잘 쓰이지 않습니다.
1. 일단 요청이 많이 왔지만 Circuit Breaker는 열리기 전이라는 짧은 순간도 무중단으로 운영되야 되는 시스템이 아니면 크게 의미가 없습니다. Circuit Breaker는 생각보다 빨리 열립니다.
2. 관리하는 비용이 생각보다 큽니다. Thread Pool 뿐만 아니라 Connection Pool 등도 Bulkhead를 적용해야 시스템 전체의 에러를 방지할 수 있기 때문입니다.
그래서 보통 중요한 시스템 일부에만 Bulkhead를 적용합니다. 회원 관련 서비스나, Gateway 같은 서비스가 대표적인 예입니다.
'👨💻 프로그래밍 > Architecture' 카테고리의 다른 글
Redis, RabbitMQ, Kafka를 각각 Message Queue로 사용할 때의 장단점 (1) | 2023.09.30 |
---|---|
🔒 분산 Architecture에서 Redlock으로 Lock 걸기 (0) | 2023.09.28 |
Spring Cloud Config로 Config 서버 구성하기 (0) | 2023.05.02 |
로드 밸런서(Load Balancer)에 쓰이는 알고리즘 (0) | 2023.04.01 |
마이크로서비스(MSA)를 쓰는 이유 (0) | 2023.03.28 |