MSA 장애전파
장애전파의 문제점
간단하게 MSA의 장점으로는 한 서비스는 다른 서비스에 영향을 안 끼치는것이다.
하지만 다른 서비스에 의존성이 있는 서비스들은 영향을 끼친다. 즉 MSA에서 서비스간 장애가 전파될 때가 있다.
마이크로 서비스 아키텍쳐 패턴은 시스템을 여러개의 서비스 컴포넌트로 나눠서 서비스 컴포넌트간에 호출하는 개념을 가지고 있다. 이로 인해 생기는 문제점은
하나의 컴포넌트가 느려지거나 장애가 나면 그 장애가 난 컴포넌트를 호출하는 종속된 컴포넌트까지 장애가 전파된다.
예시
과도한 트래픽에 의한 장애 가정
- 서비스는 감당할 수 있는 Request의 수를 정핸호고 그 이상의 Request가 오게 되면 큐에 쌓이게 되고 순차적으로 처리된다.
- 서비스B는 과도한 트래픽으로 인해 큐에 많은 수의 Request가 쌓여있는 상태이고.
- 서비스A는 서비스B를 호출하게 되면 큐가 다 비워질 때까지 기다려야 한다.
- 이것을 대비하여 timeout을 설정하였다.
- 그래서 서비스A가 서비스B를 호출했을 때, 설정한 timeout을 넘어가게 되면 에러를 발생시켜 무작정 기다리는 것을 방지하지만 timeout 만큼 기다려야 한다.
서비스B에 장애 가정
- 서비스A가 서비스B를 호출을 하는데, 문제가 발생해 서비스B가 응답을 못준다.
- 서비스A에서 서비스B를 호출한 쓰레드는 응답을 받지 못했기 때문에 계속 응답을 기다리는 상태로 잡혀있다.
- 지속해서 서비스A가 서비스B를 호출하게 되면 앞과 같은원리로 각 쓰레드들이 응답을 기다리는 상태로 변한다.
- 결과적으로는 남은 쓰레드가 없어 다른 요청을 처리할 수 없는 상태가 된다.
해결책
서킷 브레이커(circuit breaker)
원리
- 서비스A와 서비스B에 서킷 브레이커를 설치한다.
- 서비스B로의 모든 호출은 이 서킷 브레이커를 통과하게 되고 서비스B가 정상적인 상황에서는 트래픽을 문제 없이 bypass한다.
- 만약에 서비스B가 문제가 생겼음을 서킷 브레이커가 감지한 경우에는 서비스B로의 호출을 강제적으로 끊어서 서비스A에서 쓰레드들이 더 이상 요청을 기다리지 않도록 해서 장애가 전파하는 것을 방지한다.
- 강제적으로 호출을 끊으면 에러 메세지가 서비스A에서 발생하기 때문에 장애 전파는 막을 수 있지만, 서비스A에서 이에 대한 장애 처리 로직이 별도로 필요하다.
폴백 메시징(Fall-back)
원리
- 서킷 브레이커를 더 발전 시킨것이 폴백 메시징이다.
- 서킷 브레이커에서 서비스B가 정상적인 응답을 할 수 없을 때, 서킷 브레이커가 룰에 따라서 다른 메세지를 리턴하게 하는 방법
- 대표적으로는 Default 값을 설정
- 그렇게 되면 마비가 일어나도, 에러 없이 자연스러운 연출이 나오고
- 또한 timeout만큼 기다리지 않아도 된다.
예제
- 서비스A는 상품 목록을 화면에 뿌려주는 서비스이다.
- 서비스B는 사용자에 대해서 머신러닝을 이요하여 상품을 추천해주는 서비스이다. 그리고 서비스B가 장애가 나면 상품 추천을 해줄 수 없다.
- 이때 상품 진열자 등이 미리 추천 상품 목록을 설정해놓고(Fallback message에 설정), 서비스B에 장애가 났다.
- 서킷 브레이커에서 이 목록을 리턴해주게 하면 머신러닝 알고리즘 기반의 상품 추천보다는 정확도는 낮아지지만 최소한 시스템이 장애가 나는 것을 방지 할 수 있고 다소 낮은 확룔로라도 상품을 추천하여 꾸준하게 구매를 유도할 수 있다.