용로그
article thumbnail

분산 환경에서의 장애 전파 문제


분산 환경에서 개발을 하다 보면 외부 API를 호출해야 하는 경우가 있을 것입니다. 특히나 아키텍처가 MSA로 구성되어 있다면 다른 서비스 호출이 매우 빈번합니다.

 

하지만, 다른 서비스에 문제가 생겼을 때 장애가 전파되기가 매우 쉽습니다. 즉 A 서비스가 B 서비스를 호출하는 상황일 때 B 서비스에 장애가 발생한다면 A 서비스까지 정상적으로 동작하지 않게 되는 것이죠.

 

이런 상황에서는 장애가 발생한 서비스를 탐색하고 요청을 차단할 필요가 있습니다. 그렇지 않으면 하나의 서비스에 생긴 장애가 전체 서비스의 장애로까지 이어지기 때문입니다.

 

재시도(Retry) 패턴


만약 네트워크가 일시적으로 끊겨 요청이 처리되지 않는 경우는 간단한 재시도로 해결할 수 있습니다. 재시도 패턴(Retry Pattern)이란 예외적인 상황에 대응하기 위해 애플리케이션의 요청이 성공할 때까지 동일한 요청을 몇 번씩 보내는 설계 패턴입니다. 대상 서비스의 장애가 해결될 때까지 걸리는 시간을 고려하여 몇 초 정도 대기한 다음에 재시도할 수도 있습니다.

 

그러나 요청의 실패 원인이 네트워크 이슈와 같은 일시적인 것이 아니라면 재시도 패턴은 오히려 해가 될 수 있습니다. 재시도 패턴을 사용하면 애플리케이션은 재시도 횟수를 전부 채울 때 까지 재시도하기 때문입니다.

 

서버 애플리케이션의 경우 각 요청마다 장애가 발생한 서비스로 수차례씩 통신을 재시도하다보면, 제대로 처리하지 못한 요청들이 서버에 쌓이게 되는데, 이는 MSA 환경에서 더더욱 심각한 상황을 초래할 수도 있습니다.

 

예를 들어 MSA 구조에서 서비스 A -> 서비스 B -> 서비스 C의 관계로 의존하고 있다면 서비스 A에서 재시도 요청을 3번만 해도 총 재시도 횟수는 9번이 됩니다.

서킷 브레이커 패턴(Circuit Breaker Pattern)이란?


위 문제를 해결하기 위해 등장한 것이 서킷 브레이커 패턴(Circuit Breaker Pattern)입니다. 서킷 브레이커 패턴은 말 그대로 회로 차단기와 비슷하며, 문제가 발생한 지점을 감지하고 요청을 차단하는 역할을 합니다.

 

회로 사이 전류가 흐르는 간단한 회로 차단기를 떠올려 보겠습니다. 회로 차단기를 닫은 상태에서는 전류가 흐르게 되고, 회로가 열린 상태에서는 전류가 끊겨 흐르지 않게 됩니다.

 

 

https://martinfowler.com/bliki/CircuitBreaker.html

 

서킷 브레이커는 위 그림과 같은 상태 머신으로 나타낼 수 있습니다. 서킷 브레이크는 아래와 같은 총 3가지의 상태를 가지게 됩니다.

  • Closed : 요청을 정상적으로 처리할 수 있는 상태입니다.
  • Open : 외부 서버에 장애가 발생한 상태입니다. 더 이상 요청을 처리할 수 없으며, fallback하게 됩니다.
  • Half Open : Open 이후 일정 시간이 지난 상태입니다. 이 상태에서 요청이 성공하면 Closed로 변경되고 실패하면 Open 상태를 유지합니다.

만약 서킷 브레이커의 상태가 Open이라면 요청을 fallback 하게 됩니다. 예를 들어 이메일 발송 서비스에 장애가 발생해 서킷 브레이커의 상태가 Open이 되었다고 가정하겠습니다.

 

이때 서킷 브레이커가 열린 상태이기 때문에 더 이상 이메일 발송을 담당하는 서버에 요청을 보낼 수 없게 됩니다. 대신 이메일 발송 서버의 요청을 다른 이메일 발송 서버로 fallback 하게 만들어 정상적으로 처리할 수 있습니다.

 

Resilience4j


Resilience4j는 Spring Cloud에서 Circuit Breaker를 비롯한 다양한 Fault Tolerant를 위한 모듈을 사용할 수 있도록 제공합니다. Resilience의 의미는 회복 탄력성입니다. 회복 탄력이라는 뜻은 장애가 발생한 서버에 대해 빠르게 대처하고 스스로 회복하 수 있는 능력을 의미합니다.

 

Resilience4j를 제외한 자바 진영에서 사용할 수 있는 서킷 브레이커 라이브러리는 Hystrix라는 라이브러리가 존재합니다. Hystrix 라이브러리는 넷플릭스(Netflix)가 만든 오픈소스 라이브러리인데, 현재 유지보수 모드(maintence mode)인 상태입니다. 더 이상의 기능 개발 및 성능 최적화를 진행하지 않습니다. 실제로 Hystrix도 Resilience4j를 사용하기를 권장합니다.

profile

용로그

@용로그

벨덩보단 용덩 github.com/wonyongChoi05