웹 애플리케이션에서 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()를 사용하여 간단히 설정할 수 있습니다

image

💡 처리 흐름

  1. 클라이언트 -> STOMP 메시지 전송 (/app/chat/1)
  2. @MessageMapping("/chat/1") 핸들러에서 메시지 처리 후 응답 생성
  3. brokerChannel을 통해 메시지가 내부 브로커로 전달
  4. 내부 브로커에서 “/topic/chat/1” 채널을 구독한 클라이언트에게 메시지 전달

그렇다면 분산 환경에서는 어떻게 될까요?

웹소켓은 특정 서버와 지속적인 연결을 유지해야 하기 때문에, 서버가 여러 개일 경우 메시지가 다른 서버의 클라이언트에게 전달되지 않는 문제 가 발생할 수 있습니다

image

이러한 문제를 방지하기 위해 스프링에서는 외부 브로커를 설정할 수 있도록 지원하고 있습니다

외부 브로커

외부 브로커는 RabbitMQ나 ActiveMQ와 같은 별도의 메시지 시스템을 사용하여 메시지를 라우팅하는 방식입니다.

Spring에서는 브로커를 메시지를 릴레이하는 역할로만 사용하고, 실제 메시지와 구독 정보는 외부 브로커에서 관리됩니다.

image

💡 처리 흐름

  1. 클라이언트 -> STOMP 메시지 전송 (/app/chat/1)
  2. @MessageMapping("/chat/1") 핸들러에서 메시지 처리 후 응답 생성
  3. brokerChannel을 통해 메시지를 BrokerRelay로 전달
  4. 브로커 릴레이에서 메시지를 외부 브로커(RabbitMQ 등)로 전달
  5. 외부 브로커가 “/topic/chat/1” 채널을 구독한 모든 클라이언트에게 메시지 전달

내부 브로커 vs 외부 브로커 장단점 비교

내부 브로커

  • 장점
    • 별도의 메시지 브로커 없이 간단하게 설정할 수 있습니다.
    • 작은 규모의 애플리케이션에 적합하고, 빠르게 개발할 수 있습니다.
    • 메시징 구조가 간단하여 빠른 구현이 가능합니다.
  • 단점
    • 서버가 다운되면 메시지가 사라집니다.
    • 다중 인스턴스 환경에서는 동기화 문제가 발생할 수 있습니다.
    • 대량의 메시지를 처리해야 할 경우 부하가 증가할 수 있습니다.

외부 브로커

  • 장점
    • 여러 서버가 동일한 메시지 브로커를 공유할 수 있어, 분산 환경에서도 안정적입니다.
    • 메시지 지속성이 보장되며, 서버가 재시작되더라도 메시지가 유지됩니다.
  • 단점
    • 별도의 메시지 브로커를 운영해야 하기 때문에, 추가적인 관리가 필요합니다.
    • 설정과 유지 관리가 복잡할 수 있습니다.

3. 언제 내부 브로커를 쓰고, 언제 외부 브로커를 써야 할까?

내부 브로커

  • 단일 서버에서 운영되는 소규모 프로젝트
  • 빠르게 웹소켓을 적용하고 싶은 경우
  • 메시지의 영속성이 필요하지 않은 경우
  • 개발 및 테스트 환경에서 간단한 메시징 기능을 활용할 경우

외부 브로커

  • 다중 서버 환경에서 메시지를 공유해야 하는 경우
  • 메시지를 지속적으로 저장해야 하는 경우
  • RabbitMQ, Kafka 등 기존 메시지 브로커를 운영 중인 경우
  • 트래픽이 많아 수평 확장이 필요한 경우
  • 대량의 메시지를 안정적으로 처리해야 하는 경우

결론

STOMP를 사용한 웹소켓 메시징에서 내부 브로커와 외부 브로커는 각각 다른 장점과 단점을 가지고 있습니다.

소규모 프로젝트개발 환경에서는 내부 브로커가 유용할 수 있지만, 확장성이나 메시지 지속성이 중요한 경우에는 외부 브로커를 사용하는 것이 더 적합합니다.

이를 잘 고려하여 선택하면 성능과 확장성을 최적화 할 수 있습니다.