Unisquads
로그인
홈
이용약관·개인정보처리방침·콘텐츠정책·© 2026 Unisquads
이용약관·개인정보처리방침·콘텐츠정책
© 2026 Unisquads. All rights reserved.

STOMP (r1)

이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.14 23:11

STOMP

이름

STOMP

정식 명칭

Simple (or Streaming) Text Oriented Messaging Protocol

분류

메시징 프로토콜

계층

애플리케이션 계층

기반

TCP/IP, WebSocket

특징

텍스트 기반, 프레임 단위 통신, Pub/Sub 모델 지원

주요 용도

메시지 브로커와 클라이언트 간 통신

프로토콜 상세 정보

프레임 구조

COMMAND, 헤더, 본문, NULL 바이트로 구성

핵심 명령어

CONNECT, SEND, SUBSCRIBE, UNSUBSCRIBE, BEGIN, COMMIT, ABORT, ACK, NACK, DISCONNECT

헤더

키-값 쌍, 콜론(:)으로 구분

지원 언어

Java, JavaScript, Python, .NET 등 다수

대표 구현체

Apache ActiveMQ, RabbitMQ (플러그인), Spring Framework

대체/관련 프로토콜

AMQP, MQTT, WebSocket (전송 계층)

장점

간단한 텍스트 프로토콜로 구현 및 디버깅 용이, WebSocket과 호환성 좋음

단점

바이너리 데이터 전송 비효율적, AMQP에 비해 기능 제한적

사용 예시

실시간 웹 알림, 주식 시세 전송, 채팅 애플리케이션

1. 개요

STOMP(Simple Text Oriented Messaging Protocol)는 단순 텍스트 지향 메시징 프로토콜을 의미하는 애플리케이션 계층 프로토콜이다. 이 프로토콜은 클라이언트와 서버 간에 비동기 메시지를 교환하기 위한 간단하고 상호 운용 가능한 텍스트 기반의 프레임 포맷을 정의한다. 주로 메시지 브로커를 통해 발행-구독(PUB/SUB) 및 점대점(Point-to-Point) 메시징 패턴을 구현하는 데 사용된다.

STOMP는 HTTP와 유사한 텍스트 기반의 명령어(프레임) 세트를 사용하여 동작한다. 클라이언트는 CONNECT, SEND, SUBSCRIBE, UNSUBSCRIBE, DISCONNECT 등의 명령을 보내고, 서버는 CONNECTED, MESSAGE, ERROR 등의 명령으로 응답한다. 이러한 단순성 덕분에 다양한 프로그래밍 언어와 플랫폼에서 비교적 쉽게 클라이언트와 서버를 구현할 수 있다.

이 프로토콜은 초기에 루비 온 레일즈와 애플리케이션 서버인 홍콩의 메시징을 위해 개발되었으나, 이후 Apache ActiveMQ, RabbitMQ와 같은 주요 오픈소스 메시지 브로커들에 의해 널리 채택되었다. 특히 웹소켓(WebSocket) 프로토콜과 결합된 'STOMP over WebSocket'은 실시간 양방향 통신이 필요한 현대적 웹 애플리케이션과 모바일 애플리케이션에서 중요한 역할을 한다.

2. STOMP 프로토콜의 기본 구조

STOMP 프로토콜은 클라이언트와 서버 간의 통신을 프레임 단위로 구성한다. 각 프레임은 명령어, 헤더, 본문으로 이루어지며, 프레임의 끝은 널 문자(0x00)로 표시된다. 주요 명령어에는 연결을 시작하는 CONNECT, 연결을 종료하는 DISCONNECT, 메시지를 구독하는 SUBSCRIBE, 구독을 해지하는 UNSUBSCRIBE, 목적지로 메시지를 보내는 SEND, 그리고 서버가 클라이언트에게 메시지를 전달할 때 사용하는 MESSAGE 등이 있다.

프레임 구조는 텍스트 기반으로 매우 직관적이다. 예를 들어, 메시지를 보내는 프레임은 다음과 같은 형태를 가진다.

```

SEND

destination:/queue/test

content-type:text/plain

hello queue

^@

```

첫 줄은 명령어(SEND)이며, 그 다음 줄부터 빈 줄까지는 key:value 형태의 헤더가 위치한다. 헤더 이후의 빈 줄을 구분자로 하여 본문이 시작되며, 프레임은 널 문자(^@로 표시)로 종료된다.

연결 및 세션 관리는 CONNECT와 CONNECTED 명령어를 통해 이루어진다. 클라이언트는 CONNECT 프레임을 보내어 서버에 연결을 시도하고, 필요한 경우 인증 정보(예: login, passcode 헤더)를 포함한다. 서버는 연결 요청을 수락하면 CONNECTED 프레임으로 응답하며, 이때 고유한 세션 식별자를 [session] 헤더에 담아 보낼 수 있다. 이 세션은 연결이 유지되는 동안 상태를 관리하는 데 사용된다. 연결 종료는 클라이언트가 DISCONNECT 프레임을 전송하면 완료된다.

2.1. 프레임 구조와 명령어

STOMP 프로토콜의 통신은 프레임 단위로 이루어진다. 각 프레임은 명령어, 헤더, 본문으로 구성되며, 프레임의 끝은 널 문자(0x00)로 표시된다. 이 텍스트 기반의 구조는 디버깅과 구현을 단순하게 만드는 핵심 요소이다.

주요 명령어는 다음과 같다.

명령어

설명

CONNECT/STOMP

메시지 브로커에 연결을 시도한다.

CONNECTED

브로커가 성공적인 연결을 응답한다.

SEND

메시지를 특정 목적지(예: /queue/foo 또는 /topic/bar)로 전송한다.

SUBSCRIBE

특정 목적지로부터 메시지를 수신하기 위해 구독을 요청한다.

UNSUBSCRIBE

이전의 구독을 취소한다.

MESSAGE

브로커가 구독자 클라이언트에게 메시지를 전달한다.

ACK/NACK

클라이언트가 메시지 수신을 확인(ACK)하거나 실패(NACK)를 알린다.

BEGIN/COMMIT/ABORT

메시지 처리의 트랜잭션을 제어한다.

DISCONNECT

연결을 종료한다.

헤더는 키:값 쌍으로 이루어지며, 명령어에 필요한 부가 정보를 담는다. 예를 들어, SEND 프레임에는 메시지가 전송될 목적지를 나타내는 destination 헤더가 필수적으로 포함된다. SUBSCRIBE 프레임에는 구독을 식별하는 id 헤더가 필요하다. 본문은 선택 사항이며, 일반적으로 JSON이나 XML과 같은 구조화된 텍스트 데이터를 담는다. 본문의 끝은 널 문자로 구분되며, 본문의 형식과 길이는 content-type과 content-length 헤더로 명시할 수 있다.

2.2. 연결 및 세션 관리

STOMP 클라이언트는 브로커에 연결하기 위해 CONNECT 또는 STOMP 프레임을 전송합니다. 이 프레임에는 인증을 위한 login과 passcode 헤더, 요청된 프로토콜 버전을 명시하는 accept-version 헤더 등을 포함할 수 있습니다. 브로커는 연결 요청을 처리한 후, 성공 시 CONNECTED 프레임으로, 실패 시 ERROR 프레임으로 응답합니다. 연결이 수립되면 TCP 소켓 또는 웹소켓과 같은 전송 계층 연결 위에 논리적인 STOMP 세션이 생성됩니다.

세션은 연결된 상태에서 클라이언트와 브로커 간의 메시지 교환을 관리하는 기본 단위입니다. 하나의 물리적 연결 내에서 여러 개의 논리적 구독(Subscription)이 생성되고 관리될 수 있습니다. 각 구독은 고유한 id 헤더로 식별되며, 클라이언트는 SUBSCRIBE 프레임으로 특정 목적지(예: 토픽 또는 큐)를 구독하고, UNSUBSCRIBE 프레임으로 구독을 해제합니다.

연결을 종료하려면 클라이언트가 DISCONNECT 프레임을 전송합니다. 브로커는 이 프레임을 받으면 해당 클라이언트와 관련된 모든 리소스(세션, 미확인 메시지, 구독 등)를 정리한 후 전송 계층 연결을 닫습니다. 비정상적 종료 시에도 브로커는 세션 리소스를 정리하는 것이 일반적입니다. 세션 관리의 핵심은 연결, 구독 라이프사이클, 그리고 정리 과정을 통해 메시지의 신뢰성과 순서를 보장하는 데 있습니다.

3. STOMP의 주요 특징

STOMP는 메시지 지향 미들웨어 간 통신을 위한 텍스트 기반의 단순한 프로토콜이다. 이 프로토콜의 주요 특징은 인간이 읽을 수 있는 텍스트 형식, 다양한 메시징 패턴 지원, 그리고 확장 가능한 헤더 시스템에 있다.

프로토콜은 PUB/SUB와 큐 기반 메시징을 모두 지원한다. 클라이언트는 특정 목적지(Destination)를 구독(SUBSCRIBE)하여 메시지를 수신하거나, 해당 목적지로 메시지를 발행(SEND)할 수 있다. 목적지는 일반적으로 토픽(다중 구독자) 또는 큐(단일 구독자)의 개념으로 구현된다. 이는 실시간 데이터 배포와 작업 큐 처리라는 두 가지 주요 메시징 요구사항을 하나의 프로토콜로 해결할 수 있게 한다.

프로토콜의 구조는 헤더와 본문으로 구성되며, 이는 HTTP와 유사한 형태를 띤다. 헤더는 키-값 쌍으로 이루어져 있으며, 표준 헤더 외에도 사용자 정의 헤더를 추가할 수 있어 프로토콜을 유연하게 확장하는 것이 가능하다. 본문은 텍스트 또는 바이너리 데이터를 담을 수 있으며, content-type 헤더를 통해 그 형식을 명시한다. 다음은 주요 명령어와 그 역할을 보여주는 표이다.

명령어

방향

주요 역할

CONNECT/CONNECTED

클라이언트→브로커 / 브로커→클라이언트

연결 수립 및 인증

SEND

클라이언트→브로커

메시지를 목적지로 발행

SUBSCRIBE/UNSUBSCRIBE

클라이언트→브로커

목적지 구독 및 구독 해지

MESSAGE

브로커→클라이언트

구독한 목적지로부터 메시지 전달

ACK/NACK

클라이언트→브로커

메시지 수신 확인 또는 실패 처리

DISCONNECT

클라이언트→브로커

연결 종료

이러한 단순성과 유연성 덕분에 STOMP는 다양한 언어와 플랫폼에서 쉽게 구현되고, 웹소켓과 결합하여 웹 브라우저에서도 효율적으로 사용될 수 있다. 프로토콜의 최소주의적 설계는 네트워크 대역폭을 절약하고 디버깅을 용이하게 하는 장점을 제공한다.

3.1. 텍스트 기반의 단순성

STOMP는 단순 텍스트 기반 프로토콜로 설계되었다. 이는 프로토콜의 프레임 구조와 명령어가 모두 사람이 읽을 수 있는 일반 텍스트 형식을 사용한다는 것을 의미한다. 예를 들어, 메시지를 보내는 CONNECT 명령이나 메시지를 구독하는 SUBSCRIBE 명령은 모두 영어 단어로 구성되어 있으며, 헤더와 본문도 UTF-8로 인코딩된 문자열로 표현된다. 이러한 텍스트 기반 특성은 프로토콜의 동작을 직관적으로 이해하고 디버깅하는 것을 용이하게 만든다.

이 단순성은 개발과 통합 과정에서 큰 장점으로 작용한다. 네트워크 패킷을 캡처하거나 로그를 확인할 때, 전송되는 데이터의 내용을 별도의 복잡한 디코딩 과정 없이 바로 확인할 수 있다. 또한, 새로운 클라이언트나 도구를 구현할 때, 바이너리 프로토콜에 비해 파싱과 처리가 상대적으로 간단하다. 이는 AMQP나 MQTT와 같은 바이너리 중심의 프로토콜과 대비되는 STOMP의 핵심 특징 중 하나이다.

텍스트 기반 구조는 유연성과 확장성을 제공한다. 헤더는 키-값 쌍으로 자유롭게 추가할 수 있어, 메시지에 메타데이터를 첨부하거나 브로커별 특정 기능을 활용하는 데 유용하다. 본문은 텍스트(JSON, XML) 뿐만 아니라 바이너리 데이터도 문자열로 인코딩하여 전송할 수 있다. 이러한 단순함과 유연함의 결합 덕분에 STOMP는 다양한 메시징 브로커와 애플리케이션 사이의 경량 통합 계층으로 널리 채택되었다.

3.2. 메시징 패턴 지원 (PUB/SUB, 큐)

STOMP는 발행-구독 패턴과 메시지 큐라는 두 가지 주요 메시징 패턴을 명시적으로 지원합니다. 이는 프로토콜의 핵심 명령어를 통해 구현되며, 애플리케이션이 다양한 메시지 전달 방식을 선택할 수 있도록 합니다.

발행-구독(PUB/SUB) 패턴에서는 메시지 생산자(퍼블리셔)가 특정 주제(토픽)에 메시지를 발행(SEND)하고, 해당 주제를 구독(SUBSCRIBE)한 모든 소비자(서브스크라이버)가 메시지를 수신합니다. 이 패턴은 일대다(one-to-many) 통신에 적합하며, 실시간 알림이나 주식 시세 배포와 같은 시나리오에서 널리 사용됩니다. STOMP 클라이언트는 SUBSCRIBE 프레임에 destination 헤더를 지정하여 관심 있는 주제를 등록합니다. 이후 브로커는 해당 목적지로 전송된 모든 SEND 프레임을 MESSAGE 프레임으로 변환해 구독자에게 전달합니다.

메시지 큐 패턴에서는 메시지가 명명된 큐에 전송됩니다. 큐에 도착한 메시지는 일반적으로 하나의 소비자에게만 전달되며, 소비자가 메시지를 성공적으로 처리하고 확인 응답(ACK)을 보내면 큐에서 제거됩니다. 이는 작업 분산이나 로드 밸런싱과 같은 일대일(one-to-one) 통신 시나리오에 적합합니다. STOMP에서 큐 기반 통신도 destination 헤더를 통해 이루어지며, 브로커는 이를 통해 특정 큐를 식별합니다. 클라이언트는 SUBSCRIBE 시 ack 헤더를 설정하여 메시지 수신 확인 방식을 제어할 수 있습니다.

패턴

명령어 흐름

주요 특징

적합한 사용 사례

발행-구독 (PUB/SUB)

퍼블리셔: SEND → 토픽

브로커: MESSAGE → 모든 구독자

일대다(one-to-many) 브로드캐스트, 느슨한 결합

실시간 알림, 뉴스 피드, 주식 시세

메시지 큐

생산자: SEND → 큐

브로커: MESSAGE → 한 명의 소비자

일대일(one-to-one), 로드 밸런싱, 신뢰성 있는 전달

작업 큐, 주문 처리, 백그라운드 작업

두 패턴 모두 destination 헤더 값의 네이밍 규칙(예: /topic/주제이름 또는 /queue/큐이름)에 의해 구분되거나, 브로커의 내부 정책에 의해 결정됩니다. 이 유연성 덕분에 개발자는 단일하고 단순한 프로토콜을 사용하여 복잡한 메시징 토폴로지를 구성할 수 있습니다.

3.3. 헤더와 본문의 유연성

STOMP 프레임은 헤더와 본문으로 구성되며, 이 두 부분 모두 유연한 구조를 가진다. 헤더는 키-값 쌍의 집합으로, 메시지의 메타데이터를 전달하는 역할을 한다. 표준 헤더 외에도 사용자가 임의의 커스텀 헤더를 정의하고 추가할 수 있어, 애플리케이션별 특수한 정보나 라우팅 지시를 포함시키는 것이 가능하다. 예를 들어, 거래 ID나 사용자 정의 우선순위 등을 헤더에 담아 보낼 수 있다.

본문은 선택적이며, 텍스트 또는 바이너리 데이터를 담을 수 있다. 본문의 내용 형식은 content-type 헤더를 통해 명시된다. 일반적으로 JSON이나 XML 같은 텍스트 형식이 널리 사용되지만, 필요에 따라 이미지나 프로토콜 버퍼 같은 바이너리 데이터도 전송할 수 있다. 본문의 길이는 content-length 헤더로 표시된다.

이러한 유연성은 다양한 메시징 요구사항을 충족시킨다. 간단한 텍스트 명령부터 구조화된 데이터나 파일 스트림까지, 단일하고 간결한 프레임 구조 안에서 처리할 수 있다. 다음은 STOMP SEND 프레임의 구조 예시이다.

구성 요소

설명

예시

명령어

수행할 동작

SEND

헤더

메타데이터 (필수+선택)

`destination:/queue/test

content-type:application/json`

본문

전송할 실제 데이터 (선택)

{"type":"notice","msg":"Hello"}

널 문자

프레임 종료 표시

^@ (16진수 0x00)

유연한 헤더와 본문 설계는 STOMP를 교차 플랫폼 통신과 이기종 시스템 간 통합에 적합하게 만드는 핵심 요소 중 하나이다. 프로토콜 자체는 전송 형식에 구애받지 않으면서, 애플리케이션 계층에서 필요한 모든 정보를 효율적으로 포장할 수 있는 수단을 제공한다.

4. STOMP 클라이언트와 브로커

STOMP 프로토콜을 사용하는 시스템은 클라이언트와 브로커라는 두 주요 구성 요소로 이루어진다. 클라이언트는 메시지를 생산하거나 소비하는 애플리케이션을 의미하며, 브로커는 메시지를 중계하고 라우팅하는 서버 역할을 담당한다. 이 둘 사이의 통신은 STOMP 프레임을 통해 이루어진다.

클라이언트 측에는 다양한 프로그래밍 언어와 플랫폼을 위한 구현체가 존재한다. 웹 브라우저 환경에서는 JavaScript 기반의 stomp.js 라이브러리가 널리 사용된다. 서버 사이드 자바 애플리케이션에서는 Spring Framework의 Spring STOMP 모듈이 강력한 지원을 제공하며, CONNECT, SEND, SUBSCRIBE 등의 명령어 처리를 추상화한다. 그 외에도 Python, .NET, Go 등 주요 언어용 STOMP 클라이언트 라이브러리가 활발히 개발되고 있다.

STOMP 브로커는 프로토콜을 이해하고 메시지를 적절한 목적지로 전달하는 메시지 미들웨어이다. 대표적인 오픈소스 메시지 브로커들은 대부분 STOMP 프로토콜을 지원한다. Apache ActiveMQ와 그 후속인 ActiveMQ Artemis는 STOMP를 네이티브 프로토콜 중 하나로 제공한다. RabbitMQ는 STOMP 플러그인을 설치하여 지원할 수 있다. Apache Kafka는 주로 자체 프로토콜을 사용하지만, STOMP를 통한 접근을 가능하게 하는 커넥터가 존재한다.

클라이언트와 브로커의 호환성은 일반적으로 높은 편이지만, 몇 가지 고려사항이 있다.

브로커

STOMP 지원 방식

주요 특징

ActiveMQ/Artemis

내장 지원

JMS 기반, 대규모 엔터프라이즈 환경에 적합

RabbitMQ

플러그인 설치 필요

AMQP 기반, 경량화 및 높은 처리량

Apache Kafka

커넥터(예: Strimzi) 필요

높은 처리량의 로그 기반 메시징

브로커 선택은 지연 시간, 처리량, 지속성, 클러스터링 기능 등 애플리케이션의 요구사항에 따라 결정된다. 모든 브로커가 STOMP 사양의 모든 선택적 기능(예: 영수증, 트랜잭션)을 완전히 구현하지는 않을 수 있으므로, 사용 전에 호환성을 확인하는 것이 필요하다.

4.1. 클라이언트 구현체 (예: stomp.js, Spring STOMP)

다양한 프로그래밍 언어와 플랫폼을 위해 여러 STOMP 클라이언트 구현체가 존재한다. 이 구현체들은 프로토콜 사양을 준수하며, 애플리케이션에서 STOMP 브로커와의 통신을 쉽게 구현할 수 있도록 API를 제공한다.

웹 브라우저 환경에서는 JavaScript 라이브러리인 stomp.js가 널리 사용된다. 이 라이브러리는 WebSocket 또는 SockJS를 전송 계층으로 사용하여 서버와의 실시간 양방향 통신을 가능하게 한다. stomp.js는 PUB/SUB 및 큐 기반 메시징을 지원하며, 연결 관리, 구독, 메시지 송수신을 위한 간결한 메서드를 제공한다.

서버 측 Java 애플리케이션에서는 Spring Framework의 Spring STOMP 모듈이 강력한 지원을 한다. Spring Boot와 통합되어 손쉽게 STOMP over WebSocket 엔드포인트를 구성할 수 있다. 이 모듈은 메시지 라우팅을 위한 @MessageMapping 어노테이션, 클라이언트 세션 관리, 메시지 전송 인터셉터 등 고급 기능을 포함한다. 다른 언어의 구현체로는 Python의 stomp.py, Go의 go-stomp, .NET용 Stomp.Net 등이 있다.

언어/플랫폼

주요 구현체

주요 특징

JavaScript (브라우저/Node.js)

stomp.js

WebSocket/SockJS 기반, 경량 라이브러리

Java

Spring STOMP

Spring Framework 통합, 어노테이션 기반 구성

Python

stomp.py

스레드 안전성 지원, 여러 브로커와 호환

Go

go-stomp

간결한 API, 네이티브 Go 구현

이러한 클라이언트 라이브러리들은 개발자가 저수준의 프로토콜 처리보다 비즈니스 로직에 집중할 수 있도록 하여, STOMP 프로토콜의 채택과 실시간 애플리케이션 개발을 촉진한다.

4.2. 호환되는 메시지 브로커 (예: RabbitMQ, ActiveMQ)

STOMP는 단순한 텍스트 기반 프로토콜이기 때문에, 이를 지원하는 다양한 메시지 브로커와의 호환성이 주요 장점 중 하나이다. 대표적인 오픈소스 메시지 브로커인 Apache ActiveMQ와 RabbitMQ는 STOMP 프로토콜을 기본적으로 또는 플러그인을 통해 광범위하게 지원한다. 또한 Apache Artemis, NATS, HornetQ와 같은 다른 브로커들도 STOMP를 구현하고 있다[1].

각 브로커는 STOMP를 구현하는 방식과 제공하는 추가 기능에서 차이를 보인다. ActiveMQ는 자바 기반의 메시지 브로커로, STOMP를 네이티브 프로토콜 중 하나로 지원하며, JMS와의 통합이 용이하다는 특징이 있다. 반면, Erlang으로 작성된 RabbitMQ는 공식 STOMP 플러그인을 활성화함으로써 STOMP 지원을 추가한다. RabbitMQ는 AMQP가 기본 프로토콜이지만, STOMP 플러그인을 통해 더 넓은 범위의 클라이언트 접근성을 제공한다.

브로커 선택 시 고려해야 할 주요 사항은 다음과 같다.

브로커

STOMP 지원 방식

주요 특징

Apache ActiveMQ / Artemis

네이티브 지원

JMS와의 깊은 통합, 다양한 프로토콜 지원

RabbitMQ

플러그인 활성화 필요

높은 성능과 안정성, 클러스터링 용이

NATS

네이티브 지원

경량화 및 고속 퍼블리시-서브스크라이브에 중점

이러한 호환성 덕분에 개발자는 애플리케이션의 요구사항(예: 처리량, 지속성, 클러스터링)에 맞는 브로커를 선택한 후, 표준화된 STOMP 클라이언트 라이브러리를 사용하여 통신할 수 있다. 이는 벤더 종속성을 줄이고 시스템 통합의 유연성을 높이는 데 기여한다.

5. 웹소켓과의 연동

웹소켓은 TCP 연결 위에서 전이중 통신 채널을 제공하는 프로토콜이다. STOMP는 웹소켓 위에서 동작하는 하위 프로토콜로 사용될 수 있으며, 이 조합은 'STOMP over WebSocket'으로 불린다. 웹소켓 연결이 수립된 후, 클라이언트는 일반 텍스트 또는 이진 웹소켓 프레임 안에 STOMP 프레임을 담아 전송한다. 이를 통해 기존의 STOMP 명령어와 메시징 시맨틱을 그대로 유지하면서도, HTTP 핸드셰이크와 폴링 오버헤드 없이 브라우저와 서버 간 효율적인 실시간 통신이 가능해진다.

실시간 웹 애플리케이션에서 이 조합은 널리 활용된다. 클라이언트(주로 웹 브라우저)는 stomp.js와 같은 라이브러리를 사용해 웹소켓 연결을 연 후 STOMP 프로토콜을 사용하여 서버의 메시지 브로커에 구독(SUBSCRIBE)하거나 메시지를 발행(SEND)한다. 서버 측에서는 Spring Framework의 STOMP 지원 모듈이나 RabbitMQ의 웹 STOMP 플러그인 등을 통해 웹소켓 연결을 STOMP 브로커에 브리지하는 것이 일반적이다. 이 아키텍처는 단일 연결을 통해 다수의 가상 채널(목적지)을 관리할 수 있게 해주며, Pub/Sub 및 점대점 메시징 패턴을 웹 클라이언트에 제공한다.

주요 활용 방식은 다음과 같다.

구성 요소

역할

웹 브라우저

WebSocket API와 stomp.js 클라이언트를 사용해 연결

웹소켓 서버/게이트웨이

웹소켓 연결을 수락하고 STOMP 프레임을 변환/라우팅

STOMP 호환 메시지 브로커 (예: ActiveMQ, RabbitMQ)

실제 메시지의 라우팅, 큐잉, 구독 관리 수행

백엔드 애플리케이션 서버

메시지를 브로커에 생산하거나 브로커로부터 소비

이 방식은 실시간 주식 시세 표시, 협업 편집 도구의 상태 동기화, 대화형 알림 대시보드, 웹 기반 채팅 애플리케이션 등에 적합하다. 순수 웹소켓만 사용할 때는 애플리케이션 수준의 프로토콜을 직접 설계해야 하지만, STOMP를 사용하면 검증된 메시징 어휘(Connect, Send, Subscribe, Ack 등)와 유연한 헤더 시스템을 즉시 활용할 수 있어 개발 효율성이 높아진다.

5.1. STOMP over WebSocket 동작 방식

STOMP over WebSocket은 웹소켓 연결 위에 STOMP 프로토콜을 얹어 동작하는 방식이다. 웹소켓은 TCP 연결을 통해 풀듀플렉스 통신 채널을 제공하지만, 그 자체로는 메시지의 형식이나 의미를 정의하지 않는 단순한 바이너리 프레임 전송 계층이다. STOMP는 이 위에서 동작하는 어플리케이션 레벨 프로토콜로, 클라이언트와 브로커가 교환할 메시지의 구조와 의미를 규정한다. 따라서 웹 브라우저와 같은 웹소켓 클라이언트는 STOMP 프로토콜을 구현함으로써 메시지 브로커와 직접 대화할 수 있게 된다.

동작 방식은 먼저 표준 웹소켓 핸드셰이크를 통해 연결을 수립한 후, STOMP 프레임을 웹소켓 메시지의 페이로드로 전송하는 것이다. 클라이언트는 CONNECT 또는 STOMP 프레임을 보내 연결을 시작하고, 브로커는 CONNECTED 프레임으로 응답한다. 이후 모든 STOMP 명령어(SEND, SUBSCRIBE, MESSAGE 등)는 텍스트 또는 바이너리 웹소켓 메시지 안에 담겨 전송된다. 이 구조는 HTTP를 통한 폴링 방식에 비해 오버헤드가 적고 지연 시간이 짧은 실시간 양방향 통신을 가능하게 한다.

이 방식의 주요 장점은 웹 애플리케이션 개발의 편의성에 있다. 개발자는 낮은 수준의 웹소켓 API를 직접 다루지 않고, 토픽이나 큐 기반의 익숙한 메시징 모델을 사용할 수 있다. 또한 STOMP의 텍스트 기반 프레임 구조는 디버깅과 메시지 검사를 쉽게 만든다. 대부분의 현대 메시지 브로커(예: RabbitMQ, ActiveMQ)와 웹 프레임워크(예: Spring Framework의 STOMP 모듈)는 STOMP over WebSocket을 네이티브로 지원한다.

계층

역할

프로토콜/기술

어플리케이션 계층

메시징 의미 정의, 구독/발행 관리

STOMP

전송 계층

양방향 실시간 통신 채널 제공

WebSocket

네트워크 계층

신뢰성 있는 데이터 전송

TCP/IP

이러한 계층적 구조 덕분에 STOMP over WebSocket은 실시간 웹 애플리케이션, 특히 대화형 알림 시스템, 라이브 차트, 협업 편집기 및 웹 기반 채팅 애플리케이션을 구축하는 데 널리 채택된다.

5.2. 실시간 웹 애플리케이션에서의 활용

웹소켓은 양방향 통신 채널을 제공하지만, 전송할 메시지의 형식에 대해서는 규정하지 않는다. STOMP는 이 위에 메시징 시맨틱(의미 체계)을 정의하는 프로토콜 계층으로 작동하여, 클라이언트와 서버가 구조화된 방식으로 메시지를 교환할 수 있게 한다.

이 조합은 실시간 웹 애플리케이션의 핵심 요구사항을 충족시킨다. 클라이언트는 CONNECT 프레임으로 브로커에 연결한 후, 특정 주제(destination)를 SUBSCRIBE하여 구독할 수 있다. 서버나 다른 클라이언트가 해당 주제에 메시지를 PUBLISH하면, 브로커는 실시간으로 모든 구독자에게 MESSAGE 프레임을 전달한다. 이 Pub/Sub(발행-구독) 패턴은 특정 사용자나 그룹에게만 메시지를 전달하는 선택적 브로드캐스트를 가능하게 한다.

주요 활용 예시는 다음과 같다.

활용 분야

STOMP의 역할

실시간 채팅

사용자는 특정 채팅방(주제)을 구독하고, 메시지 발송 시 모든 참가자에게 실시간 전달[2].

라이브 알림

주식 가격 변동, 소셜 미디어 알림, 시스템 이벤트 등을 특정 채널을 구독한 사용자에게 즉시 푸시.

협업 도구

문서의 실시간 공동 편집에서 커서 위치나 텍스트 변경 사항을 모든 편집자에게 동기화.

대시보드

서버 모니터링, IoT 센서 데이터 등 실시간 변동 데이터를 웹 기반 대시보드에 지속적으로 업데이트.

이러한 활용은 Spring Framework의 STOMP 지원이나 stomp.js 라이브러리와 같은 도구를 통해 쉽게 구현된다. 개발자는 낮은 수준의 웹소켓 API를 직접 다루지 않고, 토픽 기반의 메시징 모델에 집중하여 확장성 있고 유지보수 가능한 실시간 기능을 구축할 수 있다.

6. STOMP의 장단점

STOMP는 단순한 텍스트 기반 프로토콜로서, AMQP나 MQTT 같은 다른 메시징 프로토콜과 비교했을 때 명확한 장점과 한계를 가진다.

주요 장점은 설계의 단순성과 구현 용이성이다. 프로토콜 스펙이 간결하여 학습 곡선이 낮고, 프레임 구조가 직관적이다. 이는 헤더와 본문으로 구성된 텍스트 기반 프레임 덕분에 디버깅과 프로토타이핑이 쉽다는 것을 의미한다. 또한, PUB/SUB와 큐 기반 메시징 패턴을 모두 지원하며, 사용자 정의 헤더를 통해 프로토콜을 확장할 수 있는 유연성을 제공한다. 특히 웹소켓 위에서 동작하는 STOMP는 웹 브라우저가 완전한 메시징 클라이언트가 될 수 있게 하여, 실시간 웹 애플리케이션 구축에 매우 적합하다.

반면, STOMP의 단점은 기능과 성능 측면에서의 제한사항에서 비롯된다. 프로토콜이 단순한 만큼 AMQP가 제공하는 고급 메시징 보증, 정교한 라우팅, 트랜잭션 관리 등의 기능이 부족하다. 메시지 크기와 처리량 측면에서도 바이너리 프로토콜인 MQTT에 비해 오버헤드가 크기 때문에, 대역폭이 제한되거나 저사양 IoT 기기 환경에는 덜 최적화되어 있다. 다음 표는 주요 메시징 프로토콜 간의 간략한 비교를 보여준다.

비교 항목

STOMP

AMQP

MQTT

프로토콜 형식

텍스트 기반

바이너리 기반

바이너리 기반

주요 강점

단순성, 웹 친화적

기능의 풍부함, 신뢰성

경량성, 저대역폭

적합한 사용 사례

실시간 웹앱, 채팅

복잡한 엔터프라이즈 메시징

IoT, 모바일 푸시

결론적으로, STOMP는 복잡한 엔터프라이즈 통합보다는 실시간 웹 기능이나 상대적으로 단순한 애플리케이션 간 통신에 적합한 프로토콜이다. 프로젝트의 요구사항, 특히 복잡성 대 단순성, 웹 클라이언트 지원 필요성, 네트워크 제약 조건 등을 고려하여 선택해야 한다.

6.1. 다른 메시징 프로토콜 (예: AMQP, MQTT)과의 비교

STOMP는 AMQP나 MQTT와 같은 다른 메시징 프로토콜과 비교했을 때, 설계 목적과 복잡성, 사용 영역에서 차이를 보입니다. 아래 표는 주요 특성을 비교한 것입니다.

특성

STOMP

AMQP

MQTT

프로토콜 설계

단순한 텍스트 기반 프로토콜

기능이 풍부한 이진 프로토콜

경량의 이진 프로토콜

주요 목적

다양한 언어/플랫폼 간의 상호 운용성 간소화

엔터프라이즈급 신뢰성 있는 메시징

제한된 대역폭과 불안정한 네트워크 환경(예: IoT)

메시징 모델

PUB/SUB, 큐 등 기본 모델 지원

교환기, 큐, 바인딩을 통한 고급 라우팅 모델

토픽 기반 PUB/SUB

헤더/본문

텍스트 헤더와 선택적 텍스트/이진 본문

구조화된 이진 프레임과 속성

고정된 작은 헤더와 이진 페이로드

복잡성

매우 낮음. 구현이 쉬움

높음. 광범위한 기능과 보증 제공

매우 낮음. 최소한의 기능 집중

STOMP의 가장 큰 장점은 텍스트 기반의 단순함과 낮은 진입 장벽이다. HTTP와 유사한 텍스트 명령어를 사용하기 때문에 디버깅이 쉽고, 다양한 프로그래밍 언어로 클라이언트를 빠르게 구현할 수 있다. 이는 AMQP의 복잡한 이진 프레임 구조와 대비되는 점이다. 반면, AMQP는 트랜잭션, 발행 확인, 정교한 라우팅과 같은 고급 메시징 보증과 기능을 제공하여 금융 거래와 같은 엔터프라이즈 시나리오에서 더 강력한 신뢰성을 보장한다.

MQTT는 STOMP와 마찬가지로 비교적 단순하지만, 설계 철학이 근본적으로 다르다. MQTT는 네트워크 대역폭이 제한되고 연결이 불안정할 수 있는 IoT 장치에 최적화되어 있다. 따라서 프로토콜 오버헤드를 극도로 줄이고, 작은 코드 풋프린트로 구현할 수 있도록 했다. STOMP는 MQTT보다 더 유연한 헤더를 지원하지만, 기본적인 PUB/SUB 모델에서는 MQTT의 경량성과 효율성을 따라가지 못한다. 결국, STOMP는 웹 및 일반 애플리케이션에서의 쉬운 활용, AMQP는 고신뢰성 비즈니스 메시징, MQTT는 제한된 환경의 기기 간 통신에 각각 적합한 프로토콜이다.

7. 주요 사용 사례

STOMP는 단순한 텍스트 기반 프로토콜로, 다양한 실시간 메시징 요구 사항을 충족하는 데 널리 사용된다. 주요 사용 사례는 PUB/SUB 및 점대점 메시징 패턴을 필요로 하는 애플리케이션에 집중된다.

실시간 알림 시스템은 대표적인 사례이다. 사용자에게 푸시 알림, 시스템 상태 업데이트, 이벤트 발생 통보 등을 지연 없이 전달해야 하는 경우, STOMP 클라이언트는 특정 토픽을 구독하여 메시지를 수신한다. 금융 분야의 주식 거래 시스템에서는 빠른 시세 변동 정보를 다수의 트레이더에게 브로드캐스트하는 데 적합하다. 낮은 오버헤드와 명확한 프레임 구조는 고빈도 데이터 스트리밍에 유리한 환경을 제공한다[3].

협업 도구 및 채팅 애플리케이션에서도 STOMP는 핵심 역할을 한다. 다수의 사용자가 참여하는 채팅방은 하나의 토픽으로 모델링될 수 있으며, 메시지 전송(SEND)과 구독(SUBSCRIBE) 명령어를 통해 실시간 대화를 구현한다. 또한 작업 내역 공유, 문서 동시 편집 알림, 사용자 접속 상태 관리와 같은 기능에도 적용된다. 게임에서의 실시간 상태 동기화나 IoT 장치의 간단한 제어 명령 전달에도 사용되는 등, 그 활용 범위는 지속적으로 확장되고 있다.

7.1. 실시간 알림 시스템

실시간 알림 시스템은 STOMP가 가장 널리 활용되는 분야 중 하나이다. 발행-구독 패턴을 기본으로 지원하는 STOMP의 특성은 다수의 사용자에게 동시에 알림을 배포하는 데 매우 적합하다. 서버는 특정 토픽에 알림 메시지를 발행하기만 하면, 해당 토픽을 구독하고 있는 모든 클라이언트에게 메시지가 실시간으로 전달된다. 이 방식은 폴링 방식에 비해 네트워크 부하를 줄이고 지연 시간을 최소화하는 장점을 가진다.

주요 활용 예로는 소셜 미디어의 좋아요나 댓글 알림, 이커머스 플랫폼의 주문 상태 변경 알림, 모니터링 시스템의 장애 발생 알림 등이 있다. 클라이언트는 초기 연결 시 자신이 관심 있는 알림 채널(예: /user/{id}/notifications 또는 /topic/order-updates)을 구독하고, 서버는 관련 이벤트 발생 시 해당 채널로 메시지를 전송한다. 메시지 본문에는 알림 내용을 JSON이나 일반 텍스트 형식으로 담아 전송할 수 있다.

STOMP를 이용한 알림 시스템의 구현은 비교적 단순하다. 웹소켓 위에서 STOMP를 사용하면(STOMP over WebSocket) 웹 브라우저 클라이언트도 쉽게 실시간 알림을 수신할 수 있다. 또한 RabbitMQ나 ActiveMQ와 같은 메시지 브로커를 중간에 두면, 알림 서버의 확장성과 신뢰성을 높일 수 있다. 브로커는 연결된 클라이언트들을 관리하고 메시지의 지속성 또는 미전달 메시지 처리와 같은 고급 기능을 제공한다.

특징

STOMP 기반 알림 시스템의 이점

프로토콜 단순성

텍스트 기반 프로토콜로 디버깅과 구현이 용이하다.

광범위한 구독

하나의 발행으로 다수의 구독자에게 즉시 전파된다.

프레임 유연성

사용자 정의 헤더를 통해 알림 유형, 우선순위 등의 메타데이터를 추가할 수 있다.

브로커 호환성

다양한 메시지 브로커와 연동되어 엔터프라이즈급 안정성을 확보할 수 있다.

7.2. 주식 거래 시스템

STOMP는 주식 거래 시스템에서 실시간 시세 전달, 주문 실행 상태 알림, 포트폴리오 업데이트와 같은 기능을 구현하는 데 널리 사용된다. 이 프로토콜의 경량성과 텍스트 기반 구조는 빠른 개발과 다양한 클라이언트 언어 지원을 가능하게 하며, PUB/SUB 메시징 패턴은 다수의 트레이더에게 동일한 시장 데이터를 효율적으로 브로드캐스트하는 데 이상적이다.

시스템은 일반적으로 특정 주식 티커나 시장 데이터 채널을 구독하는 다수의 클라이언트를 포함한다. 예를 들어, /topic/market-data.AAPL 채널에 가격 변동 메시지를 발행하면, 해당 채널을 구독한 모든 클라이언트는 실시간으로 업데이트를 수신한다. 주문 실행과 같은 중요한 이벤트는 개별 사용자 전용 대기열(예: /queue/orders.user123)을 통해 전달되어 메시지의 신뢰성과 순서를 보장한다.

메시지 유형

STOMP 목적지 예시

전송 패턴

설명

실시간 시세

/topic/market-data.<티커>

PUB/SUB

특정 종목의 가격, 체결량 등을 모든 구독자에게 브로드캐스트

주문 확인

/queue/orders.<사용자ID>

Point-to-Point

특정 사용자에게 주문 체결, 변경, 취소 상태를 개별적으로 전달

포트폴리오 업데이트

/queue/portfolio.<계좌번호>

Point-to-Point

사용자 계좌의 자산 평가액, 보유 종목 변동 내역 전송

STOMP over WebSocket을 사용하면 웹 브라우저 기반의 트레이딩 플랫폼에서도 지연 시간이 짧은 양방향 통신을 구현할 수 있다. 이는 AMQP나 MQTT와 같은 다른 프로토콜에 비해 프로토콜의 단순함으로 인한 오버헤드가 적고, 헤더를 이용한 메타데이터(예: 메시지 유형, 타임스탬프, 주문 ID)의 유연한 첨부가 가능하기 때문이다. 따라서 고빈도 거래에는 적합하지 않을 수 있으나, 대부분의 온라인 증권사 플랫폼과 실시간 모니터링 대시보드의 요구사항을 충족시킨다.

7.3. 협업 도구 및 채팅 애플리케이션

STOMP는 PUB/SUB 메시징 패턴과 메시지 브로커를 통해 다수의 사용자 간 실시간 데이터 동기화를 효율적으로 처리할 수 있어, 협업 도구 개발에 널리 활용된다. 예를 들어, 공유 문서 편집기에서 한 사용자가 텍스트를 입력하거나 수정하면, 해당 변경 사항이 STOMP 메시지로 브로커를 통해 구독 중인 다른 모든 사용자에게 즉시 전달된다. 이를 통해 모든 참여자의 화면이 거의 동시에 갱신되어, 마치 단일 문서를 함께 편집하는 것과 같은 경험을 제공한다.

채팅 애플리케이션 또한 STOMP의 주요 사용 사례이다. 사용자는 특정 채팅방(토픽)을 구독(SUBSCRIBE)하고, 메시지를 발행(PUBLISH)함으로써 그룹 대화에 참여한다. STOMP의 간단한 텍스트 기반 프레임 구조는 채팅 메시지의 헤더(예: 보낸 사람, 시간, 대상 방)와 본문(메시지 내용)을 정의하기에 적합하다. 또한, 일대일 귓속말 기능은 특정 사용자를 목적지로 하는 개인 큐를 통해 구현될 수 있다.

애플리케이션 유형

사용되는 STOMP 패턴

주요 특징

실시간 공유 문서 편집

PUB/SUB (토픽 브로드캐스트)

문서 상태 변경 사항의 빠른 동기화

그룹 채팅

PUB/SUB (채팅방 토픽)

다대다 브로드캐스트 메시징

일대일 채팅/알림

큐(Queue) 기반 메시징

특정 수신자에게만 메시지 전달

이러한 애플리케이션들은 주로 웹소켓 위에서 STOMP를 사용(STOMP over WebSocket)하여, HTTP의 오버헤드 없이 지속적이고 양방향인 통신 채널을 확보한다. Spring Framework의 STOMP 지원이나 stomp.js 라이브러리와 같은 클라이언트 구현체를 이용하면, 개발자는 낮은 수준의 통신 프로토콜보다는 비즈니스 로직과 메시지 흐름에 더 집중할 수 있다. 결과적으로 STOMP는 실시간 협업 환경을 구축하는 데 있어 표준화되고 효율적인 메시징 백본 역할을 한다.

8. 보안 고려사항

STOMP는 기본적으로 단순한 텍스트 프로토콜로 설계되어, 자체적인 보안 메커니즘을 포함하지 않는다. 따라서 보안은 전적으로 전송 계층과 애플리케이션 구현에 의존한다. 일반적으로 STOMP는 TLS(Transport Layer Security)와 같은 암호화 채널 위에서 실행되어 도청 및 중간자 공격을 방지한다. 브로커에 대한 인증은 CONNECT 프레임 시 login과 passcode 헤더를 통해 이루어지지만, 이 자격 증명은 일반 텍스트로 전송될 수 있어 암호화된 연결이 필수적이다.

브로커 구현체는 클라이언트의 접근을 제어하기 위해 추가적인 보안 정책을 적용할 수 있다. 이는 특정 가상 호스트(virtual host)나 대상(예: 토픽, 큐)에 대한 구독 및 발행 권한을 세분화하여 관리하는 것을 포함한다. 또한, 잘못 구성되거나 악의적인 클라이언트로부터의 서비스 거부 공격을 방지하기 위해 연결 수, 프레임 크기, 요청 빈도에 대한 제한을 설정하는 것이 일반적이다.

애플리케이션 수준에서는 메시지 본문의 내용을 검증하는 것이 중요하다. STOMP는 본문에 임의의 데이터를 담을 수 있으므로, 브로커를 경유하는 모든 메시지는 신뢰할 수 없는 입력으로 간주하고 적절한 유효성 검사 및 삽입 공격 방지 조치를 취해야 한다. 특히 웹소켓을 통해 브라우저 클라이언트와 직접 통신하는 경우, 교차 출처 리소스 공유 정책과 웹소켓 보안 고려사항도 함께 적용되어야 한다.

9. 관련 문서 및 참고 자료

  • Wikipedia - STOMP

  • STOMP Protocol Specification, Version 1.2

  • Spring Framework - STOMP Support

  • Apache ActiveMQ - STOMP

  • RabbitMQ - STOMP Plugin Guide

  • Mozilla Developer Network - WebSockets API

리비전 정보

버전r1
수정일2026.02.14 23:11
편집자unisquads
편집 요약AI 자동 생성