웹 애플리케이션에서 STOMP(Simple Text Oriented Messaging Protocol) 를 이용해 웹소켓 통신을 구현할 때, 내부 브로커(in-memory broker)와 외부 브로커(external broker)를 선택할 수 있습니다.
이 두 가지 방식의 차이를 이해하면 애플리케이션의 성능과 확장성을 고려한 적절한 아키텍처를 설계할 수 있습니다.
1. 웹소켓과 STOMP란?
본론에 들어가기 앞서 웹소켓은 무엇이고, Stomp는 무엇인지 간단히 소개하겠습니다.
웹 소켓
웹소켓은 웹 애플리케이션에서 실시간, 양방향 통신을 가능하게 하는 프로토콜입니다.
단일 TCP 연결을 통해 전이중(full-duplex) 통신 채널을 제공하며, 헤더의 크기가 작고 오버헤드가 적어 효율적인 통신 가능합니다
이러한 특성 덕분에 채팅, 알림, 스트리밍 등 실시간 기능이 필요한 서비스에서 널리 사용됩니다.
Stomp(Simple Text Oriented Messaging Protocol)
STOMP는 웹소켓의 서브 프로토콜로, 클라이언트와 서버 간에 주고받는 메시지의 형식과 내용을 정의해주는 역할을 합니다.
웹소켓을 통해 양방향 통신을 할 때 메시지 형식이 표준화되어 있지 않기 때문에, STOMP를 사용하면 이 메시지 교환을 보다 체계적으로 처리할 수 있습니다.
기본 원리: pub/sub 모델
STOMP는 기본적으로 발행/구독 (pub/sub) 방식으로 동작합니다.
클라이언트가 특정 채널을 구독 (subscribe) 하면, 해당 채널에 메시지가 발행 (publish) 될 때마다, 구독한 클라이언트들에게 자동으로 전달됩니다.
이렇게 클라이언트는 자신이 관심 있는 채널만 구독하고, 해당 채널에 관련된 메시지들만 받아볼 수 있습니다.
2. 내부 브로커와 외부 브로커
웹소켓을 사용한 STOMP 메시징에서 중요한 부분 중 하나가 바로 메시지 브로커입니다.
이 메시지 브로커는 클라이언트 간의 메시지 전달을 담당하는 중요한 역할을 하며, Spring에서는 이를 내부 브로커와 외부 브로커로 선택할 수 있습니다
그럼 이제 내부 브로커와 외부 브로커를 더 자세히 알아봅시다
내부 브로커
내부 브로커는 스프링 애플리케이션 내에서 직접 메시지 라우팅을 처리하는 방식입니다
즉, 내부 브로커로 설정할 경우 스프링 어플리케이션 자체가 인 메모리를 이용해 STOMP 메세지 브로커 역할을 합니다
Spring Boot에서는 enableSimpleBroker()
를 사용하여 간단히 설정할 수 있습니다
💡 처리 흐름
- 클라이언트 -> STOMP 메시지 전송 (/app/chat/1)
@MessageMapping("/chat/1") 핸들러
에서 메시지 처리 후 응답 생성brokerChannel
을 통해 메시지가 내부 브로커로 전달- 내부 브로커에서 “/topic/chat/1” 채널을 구독한 클라이언트에게 메시지 전달
그렇다면 분산 환경에서는 어떻게 될까요?
웹소켓은 특정 서버와 지속적인 연결을 유지해야 하기 때문에, 서버가 여러 개일 경우 메시지가 다른 서버의 클라이언트에게 전달되지 않는 문제 가 발생할 수 있습니다
이러한 문제를 방지하기 위해 스프링에서는 외부 브로커를 설정할 수 있도록 지원하고 있습니다
외부 브로커
외부 브로커는 RabbitMQ나 ActiveMQ와 같은 별도의 메시지 시스템을 사용하여 메시지를 라우팅하는 방식입니다.
Spring에서는 브로커를 메시지를 릴레이하는 역할로만 사용하고, 실제 메시지와 구독 정보는 외부 브로커에서 관리됩니다.
💡 처리 흐름
- 클라이언트 -> STOMP 메시지 전송 (/app/chat/1)
@MessageMapping("/chat/1") 핸들러
에서 메시지 처리 후 응답 생성brokerChannel
을 통해 메시지를BrokerRelay
로 전달- 브로커 릴레이에서 메시지를 외부 브로커(RabbitMQ 등)로 전달
- 외부 브로커가 “/topic/chat/1” 채널을 구독한 모든 클라이언트에게 메시지 전달
내부 브로커 vs 외부 브로커 장단점 비교
내부 브로커
- 장점
- 별도의 메시지 브로커 없이 간단하게 설정할 수 있습니다.
- 작은 규모의 애플리케이션에 적합하고, 빠르게 개발할 수 있습니다.
- 메시징 구조가 간단하여 빠른 구현이 가능합니다.
- 단점
- 서버가 다운되면 메시지가 사라집니다.
- 다중 인스턴스 환경에서는 동기화 문제가 발생할 수 있습니다.
- 대량의 메시지를 처리해야 할 경우 부하가 증가할 수 있습니다.
외부 브로커
- 장점
- 여러 서버가 동일한 메시지 브로커를 공유할 수 있어, 분산 환경에서도 안정적입니다.
- 메시지 지속성이 보장되며, 서버가 재시작되더라도 메시지가 유지됩니다.
- 단점
- 별도의 메시지 브로커를 운영해야 하기 때문에, 추가적인 관리가 필요합니다.
- 설정과 유지 관리가 복잡할 수 있습니다.
3. 언제 내부 브로커를 쓰고, 언제 외부 브로커를 써야 할까?
내부 브로커
- 단일 서버에서 운영되는 소규모 프로젝트
- 빠르게 웹소켓을 적용하고 싶은 경우
- 메시지의 영속성이 필요하지 않은 경우
- 개발 및 테스트 환경에서 간단한 메시징 기능을 활용할 경우
외부 브로커
- 다중 서버 환경에서 메시지를 공유해야 하는 경우
- 메시지를 지속적으로 저장해야 하는 경우
- RabbitMQ, Kafka 등 기존 메시지 브로커를 운영 중인 경우
- 트래픽이 많아 수평 확장이 필요한 경우
- 대량의 메시지를 안정적으로 처리해야 하는 경우
결론
STOMP를 사용한 웹소켓 메시징에서 내부 브로커와 외부 브로커는 각각 다른 장점과 단점을 가지고 있습니다.
소규모 프로젝트나 개발 환경에서는 내부 브로커가 유용할 수 있지만, 확장성이나 메시지 지속성이 중요한 경우에는 외부 브로커를 사용하는 것이 더 적합합니다.
이를 잘 고려하여 선택하면 성능과 확장성을 최적화 할 수 있습니다.