Message Queue

최근 소프트웨어 아키텍쳐 추세는 더 이상 하나의 통일체가 아니라 특정 애플리케이션이 설계 의도대로 기능하도록 함께 작동해야 하는 수십 또는 수백 개의 느슨하게 결합된 컨테이너화된 요소로 구성한다.

쿠버네티스같은 컨테이너 오케스트레이션 컨테이너화 된 애플리케이션 서비스를 정리하고 상태 모니터링, 장애 조치 절차를 자동화 한다.

각 서비스가 컨테이너화 되어 나누어지면서 서로 다른 서비스가 통신하고 비동기식으로 작업을 해야하는 MQ같은 솔루션들이 필수적이라고 할 수 있다.

 

 

MQ :: Message Queue

서로 다른 소프트웨어 구성 요소 또는 시스템 간의 비동기 통신에 사용되는 기술.

안정적이고 확장 가능한 방식으로 응용 프로그램, 서비스 및 장치 간에 메시지를 교환할 수 있다.

시스템의 서로 다른 부분이 서로 비동기식으로 통신해야 하는 분산 시스템에서 자주 사용.

또한 서로 다른 서비스가 서로 메시지를 교환해야 하는 서비스 지향 아키텍처(SOA) 및 마이크로서비스 아키텍처에도 사용.

 

 

Message Queue 특징

  • 메시지의 버퍼 역할을 하며 비동기적으로 전송
  • 서비스간 느슨한 결합 가능
  • 메시지의 무손실을 보장
  • 이기종간 메시징에도 적합

 

 

기존 MQ 도입 배경

일반 사용자 데이터를 수정하는 부분에서 Auth 서버를 통한 JWT 토큰(Access Token) 인증이 필요한 부분에서

각각 컨테이너화 되어 있는 일반 비즈니스 로직과 Auth 서버간에 통신이 필요하다고 생각하였다.

 

 

그렇다면??

Kubernetes를 통해 MSA 방식 설계를 하였고 컨테이너(서비스) 간 직접 통신을 하는 방식 말고 다른 방식이 있지 않을까?? 생각을 하게되었고, 그렇게 MQ라는 미들웨어를 사용해보도록 하였다.

 

설계

 

설계 피드백

카카오 로그인 서버와 통신하는 Auth 서버와 비즈니스 로직을 처리하는 부분에서 중간에 MQ를 사용하는 것 보다, API 통신(컨테이너간 통신)이 더 바람직해보인다는 피드백을 받았다.

MQ를 도입하는 이유는 서비스의 부하를 균등하게 처리해주기 위함인데, 인증 인가를 처리하는 Auth서버로의 요청은 딱히 서비스에 부하가 걸리지 않을 것이라는 의견이였다.

 

피드백 후 생각

생각을 해보니 컨테이너간 통신에만 너무 몰입했던 것 같다. 비즈니스 로직에서 AccessToken을 Auth 서버를 통해 파싱하는 작업이 필요한데 이것은 Request, Response의 성격이 강하므로 API 요청이 맞다.

MQ를 사용한다면 Message를 Request용 Queue와 Response용 Queue 총 두 개의 큐를 사용하여 구성해야 한다고 생각이 들었고 이런 설계 방식에 대한 의문이 생김.

MQ를 왜 사용해야 하는지에 대한 의문이 들었고 단순 사용 경험보다는 어떠한 환경에서 어떤 이유로 적용했는지에 대한 설계를 해보고 도입을 해야한다고 생각이 들었다.

 

 

MQ의 도입 시나리오

  • 서비스를 분리하고 관계를 맺으려 하는 경우
  • 하지만!? 메시지 큐 활용법보다 적절한 사용 시나리오를 찾자
  • 비동기 처리를 통한 향상과 서비스간 느슨한 결합이 가져다 주는 장점을 활용
  • MSA를 고려하고 있다면 적극적/긍정적으로 고려해보자

 

채팅 서비스에서의 MQ 활용

유저A가 메시지를 보냈을 때?

  1. Chat 데이터베이스에 저장을 해야한다.
  2. 메시지를 받는 유저에게 메시지를 포워드 시켜주어야 한다.
  3. 만약에 받는 유저가 오프라인 상태라면 푸시 알림을 보내주어야 한다.
  4. 어떤 경우에는 이메일을 보내주고 싶다.

 

이 과정들을 RestAPI나 RPC 콜로 처리를 한다면 Service A는 모든 의존된 코드를 가지고 있어야 한다.

디펜던시가 많아지는 것을 Coupling이라고 하는데 시스템에 매우 좋지 않다.

 

 

예시를 들기 위해 극단적으로 생각했을 때, 메세지 보내는 요청에 대한 로직이 4초씩 걸린다고 가정하면, 모든 작업을 처리하기까지의 걸리는 시간은 총 4+4+4 = 12초가 소요된다.

 

 

미들웨어로 Message Queue를 사용한다면??

 

Service A로 메시지 요청이 들어왔을 때 MQ로 해당 Topic으로 메세지를 보내주기만 한다면, 채팅 데이터를 데이터베이스에 저장하는 일, 이메일 알림, 상대방에게 푸쉬 알림 등 모든 동작을 비동기식으로 처리할 수 있다.

여기서 비동기식(asynchronous)으로 처리한다라는 것은 결과가 나오지 않아도 기다리는 시간동안 병렬적으로 다른 작업을 수행할 수 있다라는 것을 의미하고 결국 4초라는 시간으로 3가지의 작업을 처리를 할 수 있는 셈이다.

 


 

마무리

이렇게 어떻게 MQ의 도입으로 서비스의 성능 향상과 가용성에 기여하기 위해 고민하고 시스템 설계하면서 느낀 점을 정리하다보니 MQ를 도입하기에 앞서 Why?? 라는 의문점을 먼저 던져야 한다는 것을 알았고, 개발한 서비스에 적용 해보고 싶다고 생각하게 되었다.

 

 

출처

카카오톡 시스템 디자인 | WebSocket | 메시지 큐 | SQL vs NoSQL - 코맹탈출 - 실리콘밸리 개발이야기

https://youtu.be/VODXNECZOBQ