일을 하면서 특정 이벤트 처리에 대해서 작업 할것이 생겨서
aws에 ActiveMQ 를 사용하여
JmsListener를 이용해 큐처리를하였다.
그러나 MQ에 대해서 Kafka 라는 것이 있고 대강 어떤 것 인지만 알고 있었고
자세히 어떻게 작동되는 것인지 알지 못하여 자세히 알고 넘어가고 싶어서 글을 작성합니다.
메세지 큐(Message Queue)란?
- 메세지 큐(Message Queue)란 프로세스 간에 데이터를 교환할 때 사용되는 통신 방법 중에 하나로 MOM(Message Oriented Middleware: 메세지 지향 미들웨어)를 구현한 시스템을 의미한다.
MOM(메시지 지향 미들웨어)란 비동기 메시지를 사용하는 응용 프로그램들 사이에서 데이터를 송수신하는 것을 의미한다. 여기서 메시지란 요청, 응답, 오류 메시지 혹은 단순한 정보 등의 작은 데이터가 될 수 있다. MOM을 구현한 서비스를 MQ라고 한다.
아래 그림으로 설명 하자면
메시지 큐는 메시지를 임시로 저장하는 간단한 버퍼라고 생각하면 된다.
메시지를 전송 및 수신하기 위해 중간에 Message Queue를 두는 것이다.
메시지 전송 시 생산자(Producer)로 취급되는 컴포넌트가 메시지를 메시지 큐에 추가한다. 해당 메시지는 소비자(Consumer)로 취급되는 또 다른 컴포넌트가 메시지를 검색하고 이를 사용해 어떤 작업을 수행할 때까지 메시지 큐에 저장된다. 각 메시지는 하나의 소비자에 의해 한 번만 처리될 수 있는데, 이러한 이유로 메시지 큐를 이용하는 방식을 일대일 통신이라고 부른다.
💨💨먼저 메세지 큐의 장점을 먼저 알아보자
1. 비동기(Async) : Queue에 넣어 나중에 처리가 가능.
2. 낮은 결합도(Decoupling)=비동조 : Application과 분리할 수 있다.
3. 확장성(Scalable) : 여러개의 서비스들이 큐에 메세지를 보낼 수 있다.
4. 탄력성(Resilience) : 일부가 실패해서 전체에는 영향을 주지 않는다.
5. 보장성(Guarantees) : 실패할 경우 재실행이 가능하다.
❓❔ 언제 메세지 큐를 사용할까? ❔❓
1. 이메일 전송
2. 애플리케이션 / 시스템 간 통신
3. 블로그 포스팅
4. 서버 부하가 많은 작업
5. (저희 회사에서는 입출금 기능에 메세지 큐를 사용합니다.)
일반적인 클라이언트-서버 구조에서는 사용자가 요청을 하면 서버는 그에 대한 처리를 한 후 클라이언트에게 응답을 한다. 간단한 서버 구조에서는 굳이 메시지 큐를 사용할 필요가 없다. 사용자가 응답을 기다려야 하는 HTTP 요청을 바로 처리하지 않고 중간에 메시지 큐를 두는 경우는 썩 바람직하지 않다고 한다.
또한 메시지 큐를 적용하려면 다양한 메시지 큐 중에서 시스템의 목적에 맞는 것을 선정해야 한다.
이후 선정된 메시지 큐의 사용 방법도 익혀야 하며, 지원하는 다양한 옵션 중에 시스템이 추구하는 목적에 맞는 옵션을 찾아 설정해야 한다. 상상만 해도 번거로운 작업들이 수반되는데,
왜 메시지 큐를 사용하며, 어떤 경우에 도입하는 걸까?
메시지 큐는 소비자(Consumer)가 실제로 메시지를 어느 시점에 가져가서 처리하는 지는 보장하지 않는다.
언젠가는 큐에 넣어둔 메시지가 소비되어 처리될 것이라고 믿는 것이다. 이러한 비동기적 특성 때문에 메시지 큐는 실패하면 치명적인 핵심 작업보다는 어플리케이션의 부가적인 기능에 사용하는 것이 적합하다고 한다.
위에 말한 예시들을 자세히 한번 봐보자
이메일 전송
어떤 웹 사이트의 비밀번호를 잊어버려서 이메일을 통해 임시 비밀번호를 받거나, 새로운 회원가입을 위한 인증 코드를 받아본 경험이 있을 것이다.
우리는 이러한 상황들에서 이메일이 즉각적으로 수신되기를 기대하지는 않는다. 아무리 성격이 급한 사람이라도 몇 분 안에 오겠거니 생각할 것이다. 어느 정도의 응답 지연이 허용되며, 어플리케이션의 핵심 기능은 아닌 경우이므로 메시지 큐는 이런 경우 도움이 될 수 있다.
- 이메일 전송 전용 서비스는 이메일이 어느 서비스로부터 생산되었는지와는 관계없이, 메시지 큐의 메시지를 하나씩 소비하고, 그저 이메일이 전송되어야 할 곳으로 이메일을 전송한다.
- 이와 같은 접근 방식은 메시지 큐에 들어오는 메시지 수가 너무 많아지는 경우 이메일 전송 전용 서비스 인스턴스를 더 둠으로써 확장할 수 있으므로 확장성이 뛰어나다.
애플리케이션 / 시스템 간 통신
서버 간 데이터를 주고 받거나 작업을 요청할 때, 항상 시스템 장애를 생각해야 한다.
서버가 갑자기 죽어버리거나, 서버 점검 등 다운타임이 발생하는 동안에는 요청을 주고 받을 수 없다.
서버에서 failover 처리를 해놓고 시스템이 정상적으로 돌아왔을 때 요청을 보내는 방법이 있지만, MQ를 사용하면 간편하게 처리가 가능하다.
위 사진에서 P는 Producer , C는 Consumer 를 의미한다.
- P는 C에 직접 요청을 하는것이 아닌, MQ에 메세지를 전달한다.
- C는 MQ를 구독(Subscribe)하며, MQ로 부터 메세지를 수신해서 처리한다.
- C가 수신할 수 없는 상황이라면, 메세지는 MQ에 머물렀다가 C가 받을 수 있는 상황일 때 메세지를 가져간다.
- 보통 MQ에 예상치 못한 에러 등을 생각 해, HA(High Availability: 고가용성) 클러스터 구성을 한다.
블로그 포스팅
모든 블로그 사용자가 웹에 최적화되어 있거나, 용량이 작은 이미지만 업로드하진 않을 것이다. 블로그 사용자가 게시글에 업로드한 이미지의 용량이 매우 큰 경우를 생각해보자. 블로그 서비스의 응답 시간을 저해하지 않으면서 사용자들에게 유연성을 제공하는 방법으로, 사용자가 업로드한 모든 이미지를 게시 과정에서 즉각 처리하는 것이 아닌, 사후처리하며 최적화하는 방법이 있다. 사용자 경험에 약간의 영향을 미칠 수는 있지만, 최적화는 응용 프로그램에서 가장 중요한 것은 아니며 작업을 즉시 수행할 필요도 없다. 메시지 큐는 이러한 상황에서도 사용될 수 있다.
- 사용자가 고용량의 이미지가 포함된 블로그 포스팅을 한다.
- 이미지는 저장소에 전송된다.
- 업로드된 이미지에 대한 정보가 포함된 메시지를 이미지 최적화 서비스의 메시지 큐에 담는다.
- 이미지 최적화 서비스는 저장소에서 이미지를 가져와 최적화하고, 2번에서 저장해놨던 이미지를 대체한다.
서버 부하가 많은 작업
이미지 처리, 비디오 인코딩, 빅데이터 등 대용량 데이터 처리와 같은 작업은 메모리, CPU를 많이 사용한다.
이러한 작업은 동시에 처리할 수 있는 양이 한정적이여서 무작정 요청을 보내 처리를 할 수 없다. 이럴경우, MQ를 사용하면 서버가 처리할 수 있는 양을 MQ에서 가져와 처리하면 된다.
부하분산
또한 MQ의 장점인 부하분산 처리도 가능하다. 여러 C(Consumer)를 배치해, 원하는 메세지(데이터) 처리도 가능하다. 이러한 구조는 수평적 확장(Horizontal Scaling)에 유리하다.
마지막으로
위처럼 우선적으로 다른 블로그에 있는 내용들을 보고 비교하고 정리 해보았다.
메세지 큐는 서버의 부담을 덜어주고 사용자에게도 안정성을 보장하는 좋은 시스템이라고 이해를 했다.
물론 더 공부하고 직접 다양한 예시를 통해 사용을 해보아야겠지만.
단편적으로 예시들을 조사해보면서 메세지 큐에 대해 한발짝 더 가까워 진 것 같다.
현재는 ActiveMQ를 사용하고 있기때문에 Active MQ에 대해 조금 더 공부하고 익숙해져 보아야겠다.
추 후에 kafka 까지 공부해보고 싶다!!
💌참고💌
- https://tecoble.techcourse.co.kr/post/2021-09-19-message-queue/