본 내용은 원티드 프리온보딩 과정을 회고하는 목적으로 작성되었습니다.
이번 게시물은 메시지 큐의 비동기 처리를 통한 성능 개선에 관련한 내용입니다.
메시지 큐(Message Queue) 는 메시지 기반의 중개자 소프트웨어나 서비스로 시스템 간의 또는 애플리케잇연 간의 통신을 비동기적(Asynchronous)으로 처리하는데 사용이 됩니다. 메시지 큐는 송신자, 수신자 사이의 연결을 해제 및 중개함으로써 한 시스템의 작업이 다른 시스템의 작업을 지연시키거나 방해하지 않도록 합니다. 메시지큐는 대표적으로 RabbitMQ, Apache Kafka, Amazon SQS 등의 서비스가 있습니다.
패트와 매트가 설거지를 하고있습니다. 매트(노란색 옷) 는 접시를 거품내어 닦는 역활, 패트(빨간옷) 는 접시를 행구는 역활을 담당했습니다. 설거지를 하는 과정에서 둘의 합이 잘 맞지 않는다면 어떻게 될까요?
패트가 전달받은 접시(작업)를 빠르게 닦지 못하자 매트는 닦은 접시를 전달하지 못하고 들고있으며 접시를 닦는 행위(작업)을 멈춥니다. 이는 굉장히 비효율적인 작업의 처리과정입니다.
이를 개선하고자 당연하지만!!? 매트는 다 닦은 설거지를 싱크대에 넣어 두고(Message Queue) 접시를 계속해서 닦기로 합니다. 패트는 접시가 쌓이는 것을 혼자 닦기 힘들어 그림자 분신술(서버의 다중화) 을 사용합니다.
패트1, 패트2, 패트3.. 은 역활을 분리하여 접시, 식기, 컵등을 행구어 빠르게 설거지를 끝낼 수 있게 되었습니다.
결국 핵심은! 매트와 패트가 동기적이지 않고 각각 자신의 역활을 독립적으로 수행함으로써 작업을 효율적으로 해결했으며, 이를 위해 중개자(싱크대)를 활용했다는 것 입니다.
생산자(producer) 혹은 발행자(publisher)
입력 서비스로서 메시지를 만들어 메시지 큐에 메시지를 생성(발행) 합니다.
소비자(consumer) 혹은 구독자(subscriber)
메시지를 받아 그에 맞는 동작을 수행합니다.
메시지 큐는 서비스 또는 서버간의 느슨한 결합을 도모하여, 규모 확정성이 보장되어야 하는 안정적인 애플리케이션을 구축하기에 좋습니다. 또한, 생성자는 소비자 프로세스가 다운되어도 문제없이 메시지를 발행할 수 있고, 소비자는 생산자 서비스가 다운되어도 메시지를 문제없이 수신할 수 있습니다.
따라서 메시지 큐는 메시지의 무손실(Durability: 메시지 큐에 보간된 메시지는 소비자가 꺼낼 때 까지는 안전히 보관되는 특성)을 보장합니다.
이러한 비동기 처리는 언제 사용하는게 좋을까?
커뮤니티에 게시물을 작성할 때, 생성되는 이미지 혹은 동영상을 용량별로 리사이징(re-sizing)해 저장해야하는 애플리케이션을 만든다고 가정해봅시다. (파일 입출력과 같이 리소스가 많이 소모되는 작업이 있다고 가정)
해당 작업은 단순히 JSON 데이터를 응답하는 API보다 처리하는데 시간이 오래 걸릴 수 있습니다. 이때 메시지 큐를 사용한다면 작업들을 비동기적으로 처리하여 안정적이고 빠르게 애플리케이션을 구성할 수 있습니다. (게시물 작성과 리사이징에 각각의 작업 프로세스가 동작하게 되므로 생성자는 리사이징 작업이 끝날때 까지 기다릴 필요가 없다.)
이렇게 하면 생산자와 소비자 서비스는 각기 독립적으로 확장이 가능하며 큐의 크기가 커질경우 작업 프로세스를 늘리고, 큐가 빈번히 비어있는 상태라면 작업 프로세스를 줄일 수 있습니다.
참고문헌
원티드 교육자료