마이크로 서비스 아키텍처에도 디자인 패턴이 존재한다.
그 중 하나가 바로 '리액티브 마이크로 서비스 패턴'이다.
리액티브 패턴은 기존 마이크로 서비스의 문제를 해결하기 위해 등장한 패턴으로 서비스간의 의존도를 낮추는것이 가장 큰 목적이다.
보통의 경우에 서비스 간의 통신을 위해서 RESTful API와 같은 블로킹 I/O 모델을 사용해 동기식 통신을 구현하곤 했다.
동기식 블로킹 I/O를 사용하면 서비스가 요청을 처리하는 동안 운영체제의 스레드를 점유하게 된다.
동시 요청 수가 증가하거나 요청과 관련된 컴포넌트가 증가하면 운영체제의 가용 스레드가 부족해 응답 시간이 늦어지거나 서버가 중단되는 문제가 발생할 수 있다.
따라서 동기식 블로킹 I/O를 과도하게 사용하면 마이크로서비스 시스템에 에러가 발생하기 쉽다.
예를 들어보자.
- B 서비스는 일부 메서드에서 A 서비스에 동기식 블로킹 요청을 보낸다.
- A 서비스에 에러가 발생했다.
- B 서비스에 들어온 요청들의 일부가 고장난 A 서비스를 호출하기 때문에 이들은 스레드를 점유한 채로 '동기화' 되어버린다.
- B 서비스에는 문제가 없지만 고장난 A 서비스 때문에 요청 스레드의 자원이 회수되지 못하는 것이다.
- 결국 B 서비스는 가용 스레드가 부족해져서 클라이언트의 요청을 더 이상 받지 못하게 되는 상황이 발생한다.
이런 상황은 이들과 연결된 모든 서비스들로 장애가 퍼져나가게 된다. 이것을 '연쇄 장애' 라고 한다.
이를 해결하기 위해서 논블로킹 I/O를 사용해 데이터베이스나 다른 마이크로 서비스가 처리하길 기다리는 동안 스레드가 할당되지 않게 할 수 있다.
해결책의 필요조건은 다음과 같다.
- 비동기 프로그래밍 모델을 사용한다.
즉, 메시지를 보낸 후 수신자가 메시지를 처리하길 기다리지 않는다. - 동기식 프로그래밍을 사용한다면 논블로킹 I/O를 사용해 응답을 기다리는 동안에도 스레드 할당 없이 동기식 요청을 실행하는 리액티브 프레임워크를 사용한다.
- 마이크로서비스는 의존하는 서비스가 중단되더라도 응답할 수 있도록 탄력성 있게 설계되어야 하며, 중단된 서비스가 재개되면 클라이언트가 서비스를 다시 사용할 수 있어야 한다.
'Back-End > MSA' 카테고리의 다른 글
[Cloud Native] 분산 시스템의 기초 개념들 (3) | 2022.11.05 |
---|---|
RabbitMQ, Redis, Kafka의 특징 (0) | 2022.01.18 |
모놀리식 & 마이크로서비스 아키텍처(분산 시스템) (0) | 2022.01.13 |
MSA(MicroService Architecture)에 대한 내 생각 한 줌 (6) | 2022.01.05 |