서킷 브레이킹
서킷 브레이킹에 대한 참고글: https://martinfowler.com/bliki/CircuitBreaker.html
k8s 기반 분산 아키텍처에서 발생할 수 있는 문제 중 하나는 연계 고장이다. 한 부분의 실패가 다른 부분까지 영향을 주는 것이다. 특정 마이크로서비스에 문제가 생겼다고 치자. 문제가 있는 마이크로서비스로 요청이 가게되면 response time이 증가하고 요청 자체가 실패할 가능성이 높다. 트래픽이 낮으면 문제가 없을 수 있지만, 높은 수준의 트래픽이 주어진다면, 요청이 밀려들어오면서 보류 중인 요청들이 생길 것이고 많은 요청들이 타임아웃으로 실패할 것이다.
이를 해결하고자 생긴 것이 서킷 브레이커이다. 서킷 브레이커 솔루션은 여러가지가 있는데, 대표적으로 Hystrix라는 라이브러리가 있다. 서킷브레이커를 내장한 마이크로서비스는 지나치게 많은 요청이 실패하는 경우, 모든 요청 전달을 멈추게 만든다. 즉시 503을 반환하는 것이다.
실패할 요청이 30초 동안 리소스를 잡아둔 채로 있는 것 보다, 즉시 실패하는 것이 낫다고 판단하는 것이다. 또한 마이크로서비스에게 다시 복구될 시간을 줄 수 있다. (물론 문제의 원인은 다양할 것이다.)
서킷브레이커로 넷플릭스의 Hystrix 라이브러리가 유명하지만 넷플릭스는 더 이상 해당 라이브러리를 개발하지 않는다. Hystrix는 어플리케이션에서 Hystrix 라이브러리를 활용하는 구조이고, 모든 마이크로서비스가 구축된 서킷 브레이커를 가지고 있어야 정상 동작한다. 또한 여러 언어로 구축될 수 있는 MSA 특성상 서킷 브레이커가 언어에 의존적이면 안된다.
우리는 istio 프록시를 통해 서킷 브레이커를 구성할 수 있다. 특별히 어플리케이션에 라이브러리를 적용할 필요가 없다.
만약 여러 replica중 특정 pod에 문제가 생겨 연속적으로 503을 발생시킨다면, 서킷 브레이커는 해당 pod에 부하를 막을 것이다. (간단히 말해 해당 pod에 요청을 보내지 않도록 한다.) 또한 설정을 통해, 서킷 브레이커가 주기마다 해당 pod을 다시 체크하여, 요청이 정상 처리되면 다시 정상 분산되도록 할 수 있다.
pod이 하나일 경우, 문제가 생기면 서킷 브레이커는 해당 pod을 부하 분산 풀에서 제거할 것이다. (그럼 서비스가 동작을 안하잖아? 라고 생각할 수도 있다. MSA에서는 특정 마이크로서비스가 이용 가능하지 않은 상황을 잘 견뎌야한다. 또한 오직 하나의 replica만 있는 경우, 이 pod이 일시적으로 이용불가해도 문제가 없다고 판단한 것과 마찬가지이다.)
높은 트래픽을 견디는 시스템을 구축할 경우에는 연계 고장이 발생할 가능성이 크고, 서킷 브레이킹이 유용하다. 하지만 서킷 브레이커를 허술하게 설정한다면, 서킷 브레이커가 불필요하게 작동할 수 있다.
연계 고장은 보통 잘못된 코드보다는 환경 문제 또는 네트워크 스택 어딘가에서 일어날 확률이 높다.
Istio 서킷 브레이킹 설정 (Outlier detection)
istio를 통한 서킷 브레이킹은 Destination Rule의 Outlier detection으로 설정할 수 있다.
https://istio.io/latest/docs/reference/config/networking/destination-rule/#OutlierDetection
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local # 대상 k8s 서비스명
trafficPolicy:
outlierDetection: # 서킷 브레이커 설정
maxEjectionPercent: 100
consecutive5xxErrors: 2 # 서킷 브레이커가 트리거 되기 위한 연속 오류 횟수
interval: 10s # 연속 오류 횟수에 대한 기간 (10s동안 2개의 연속 오류 발생 시 트리거)
baseEjectionTime: 30s # pod이 부하분산에서 제거되는 시간 (default: 30s), base인 이유는 두 번째로 배출되면 두 배의 시간동안 거부된다.
하나의 pod에서 10초동안 2번 연속으로 5xx 에러가 발생할 경우, 30초 동안 해당 pod이 중단될 것이다.
서킷 브레이커는 유용하지만, 민감도 설정 및 사전 테스트가 어려우며 실제 서비스시 서킷 브레이커가 트리거 되었을 때 왜 트리거 되었는지 파악이 어려울 수도 있다. 충분한 분별력을 가지고 사용해야하며 Istio를 통해 설정시 기본값을 추천한다. (ex. 10초 동안 5번의 오류 트리거)
'DevOps' 카테고리의 다른 글
[Istio] 결함 주입 (Fault Injection) (0) | 2024.01.31 |
---|---|
[Istio] Dark Release (0) | 2024.01.30 |
[Istio] Gateway & Edge Proxy (0) | 2024.01.30 |
[Istio] 로드밸런싱 (+ConsistentHashing) (0) | 2024.01.29 |
[Istio] 트래픽 관리 (+카나리 배포) (0) | 2024.01.23 |