정말 여러가지로 많이 고민했다. 작년에 캡스톤 프젝했을 때처럼 채팅 서버를 node.js를 이용해서 구현을 할까? 아니면 spring을 이용해서 해볼까?
🫤 음 ... node.js를 배우고 싶었지만, 그렇게 되면 자바스크립트 기본 밖에 모르는 내가 node.js로 채팅 서버를 구현하게 되면, 너무 시간이 많이 걸릴 것 같았다.
👌 그래서 결론은 Spring boot + STOMP + RabbitMQ를 이용해서 채팅 기능을 구현할려고 한다.
이에 관해 설명할려면, 일단 내가 왜 이 기술 스택들을 택했는지 먼저 설명하겠다.
왜 이 기술을 쓰는지 알아야지 내가 구현할 때도 납득 가능하기 때문이다.
채팅 서비스는 실시간으로 이루어지기 때문에 실시간 메시징 처리와 높은 확장성이 필요하다.
STOMP와 RabbitMQ를 사용하면 실시간 메시지 전달과 간단한 구독/발행 방식을 지원하여 이러한 요구사항을 충족시킬 수 있다.
RabbitMQ는 메시지 브로커로서 다양한 메시징 패턴 지원, 메시지 큐잉, 메시지 라우팅, 성능 및 확장성 등 다양한 기능을 제공한다.
STOMP는 간단하고 텍스트 기반의 메시징 프로토콜로서 클라이언트와 브로커 간의 통신을 처리하고 메시지를 안전하게 전달할 수 있다.
STOMP는 클라이언트와 브로커 간의 텍스트 기반 메시지 프로토콜이다.
이 프로토콜은 다양한 메세지 브로커에 적용하여 신뢰성 있는 연결을 제공하며, 구성 요소간 통신을 처리하고 메세지를 전송하는데 사용된다.
이를 통해 클라이언트가 서버에서 주고받는 메세지를 관리할수 있으며,
이경우 pub/sub과 함께 사용되어 메세지를 발신자와 수신자 사이에 전달할수 있다.
STOMP에서 클라이언트는 서버에 STOMP 명령을 보내고, 서버는 명령에 따른 응답을 제공한다.
STOMP는 메시지 발행-구독(Pub/Sub)과 지점간(Point-to-Point) 메시징 패턴을 모두 지원한다.
(Pub/Sub) 패턴에서,
발행자는 특정 주제(topic)를 지정하고,
해당 주제에 관심 있는 구독자(subscriber)는 해당 주제에 대한 구독 요청을 보냄으로써 발생한 메시지를 수신한다.
(Point-to-Point) 패턴에서는,
메시지를 전송하는 발신자(sender)와 메시지를 수신하는 수신자(receiver) 사이에서 직접 메시지가 전송된다.
메시징 시스템에서 PUB/SUB 패턴은 메시지 전송자(발행자: Publisher)와 여러 수신자(구독자: Subscriber) 간 메시지를 전달하는 방식이다. 여기서, STOMP와 RabbitMQ는 메시지를 안전하게 전달하기 위한 프로토콜과 브로커 역할을 한다.
📣 발행자(Publisher): 메시지를 발행하는 클라이언트 역할
👥 구독자(Subscriber): 메시지가 발행될 때 알림을 받는 클라이언트 역할
💌 주제(Topic): 발행된 메시지를 분류하는 데 사용되는 레이블
Publisher → Topic → Subscribers
메시지 브로커로서, 서로 다른 애플리케이션 간에 메시지를 전달하고 관리하는 역할을 수행한다. RabbitMQ의 주요 특성은 다음과 같다:
[Publisher]
▲
│
│ STOMP 메시지 전송
│
[RabbitMQ Broker] ◄─┼───► [Queue]
│
│ 구독 요청
│
│ STOMP 메시지 수신
▼
[Subscriber]
Exchange: 프로듀서로부터 받은 메시지를 적절한 큐에 전달하는 컴포넌트로, 메시지를 받아서 다양한 규칙에 따라 큐로 라우팅한다.
Queue: 작업 대기 중인 메시지의 목록으로, 컨슈머가 차례대로 처리한다.
Binding: exchange와 큐 간의 라우팅 규칙을 정의합니다. 해당 규칙의 Key와 일치하는 메시지만 전달한다.
RabbitMQ는 AMQP(Advanced Message Queuing Protocol)을 기반으로한 메시지 큐 브로커이다.
RabbitMQ를 사용하는 대부분의 시나리오에서,
메시지 발행은 프로듀서가 큐에 메시지를 전송함으로써 이루어진다.
반면, 메시지 수신은 컨슈머가 큐에서 메시지를 가져옴으로써 이루어진다.
RabbitMQ는 다양한 메시지 패턴을 지원한다. 따라서, 메시지의 발행자와 수신자 간의 관계를 두 가지 유형으로 분류할 수 있다:
RabbitMQ는 다양한 메시징 프로토콜을 지원하며, 이 중 STOMP 프로토콜을 지원한다.
RabbitMQ를 STOMP 프로토콜과 함께 사용하면, 클라이언트가 STOMP 프로토콜로 메시지를 보내고, RabbitMQ는 이를 받아서 적절한 큐나 교환기(exchange)로 라우팅하게 된다.
또한, RabbitMQ 오류 메시지와 함께 STOMP을 지원하여 메시지 전달을 더욱 신뢰성 있게 만드는 것도 가능하다.
결론적으로, STOMP와 RabbitMQ는 서로 다른 목적으로 설계된 프로토콜과 브로커이지만,
각각의 장점을 결합하여 더욱 안전하고 신뢰성 높은 메시징 시스템을 구축할 수 있다는 것을 알 수 있다.
먼저, 발행자(Publisher)는 STOMP 프로토콜을 사용해 RabbitMQ 브로커(Broker)에게 메시지를 발행(Publish) 한다.
RabbitMQ 브로커는 바로 해당 메시지를 적절한 큐(Queue)에 삽입하며,큐는 일종의 버퍼 역할을 수행한다.
이를 통해 메시지 발생 시점과 수신 시점에 차이가 발생해도 안전하게 전달될 수 있게 한다.
이후, 구독자(Subscriber)는 STOMP 프로토콜을 사용해 RabbitMQ 브로커에게 해당 메시지를 수신(Subscribe)하기를 원하는 내용을 알린다.
RabbitMQ 브로커는 구독자가 원하는 큐를 확인하고, 해당 큐의 메시지를 구독자에게 안전하게 전달(Delivery)한다.
이렇게 발행자와 구독자 모두 STOMP 프로토콜을 사용해 브로커와 통신하므로, 각각이 본인이 원하는 작업을 보낼 때 큐 형태로 쌓이고, 브로커는 그 큐에서 메시지를 처리하게 됩니다. 이렇게 구성된 메시징 시스템은 안전하고 신뢰성 높은 경로를 통해 메시지를 전달할 수 있다.