JMS 전용 속성(JMSX로 시작하는 속성)의 종류와 활용법은?
JMS(Java Message Service) 스펙은 메시지의 메타데이터를 표현하기 위해 표준 헤더(JMSMessageID, JMSTimestamp 등) 외에도 추가적인 확장 속성들을 정의하고 있습니다. 이 확장 속성들은 모두 JMSX라는 접두사로 시작하며, 메시지 브로커와 클라이언트 간의 고급 라우팅, 상태 추적, 보안, 순서 보장 등의 복잡한 엔터프라이즈 요구사항을 해결하는 데 핵심적인 역할을 합니다.
JMS 스펙에 정의된 JMSX 속성들은 메시징 벤더(ActiveMQ, Artemis, IBM MQ 등)에 따라 필수적으로 지원해야 하는 속성과 선택적으로 지원하는 속성으로 나뉩니다. 실무에서 아키텍처를 설계할 때 반드시 알아두어야 할 주요 JMSX 속성의 종류와 그 구체적인 활용법을 분석합니다.

1. 순서 보장과 병렬 처리의 핵심: JMSXGroupID 및 JMSXGroupSeq
가장 널리 쓰이고 중요한 속성입니다. 여러 컨슈머가 큐를 공유하는 분산 환경에서 특정 연관된 메시지들의 처리 순서를 엄격히 보장하기 위해 사용됩니다(Message Groups 기능).
JMSXGroupID(String):- 의미: 동일한 논리적 그룹(예: 동일한 주문 번호
ORDER-1234)에 속하는 메시지들을 식별합니다. - 활용법: 생산자(Producer)가 이 속성에 동일한 값을 세팅하여 브로커로 전송하면, 브로커는 해당
JMSXGroupID를 가진 모든 메시지를 큐에 연결된 여러 컨슈머 중 오직 단 하나의 컨슈머에게만 전담하여 라우팅합니다. 이를 통해 동시성 충돌을 막고 완벽한 순서를 보장할 수 있습니다.
JMSXGroupSeq(Integer):- 의미:
JMSXGroupID로 묶인 그룹 내에서 해당 메시지의 일련번호를 나타냅니다. - 활용법: 일반적으로 1부터 시작하여 양수로 증가합니다. 가장 중요한 활용법은 그룹을 명시적으로 종료할 때입니다. 생산자가 비즈니스 트랜잭션의 마지막 메시지에
JMSXGroupSeq = -1(혹은 0 등 브로커 설정값)을 부여하여 전송하면, 브로커는 해당 그룹의 소유권(Ownership) 매핑을 메모리에서 해제하여 메모리 누수를 방지하고 컨슈머 리밸런싱을 돕습니다.
2. 독성 메시지(Poison Pill) 방지와 재처리 추적: JMSXDeliveryCount
네트워크 장애나 컨슈머의 비즈니스 로직 오류로 인해 메시지 처리가 실패(Rollback)하면, 브로커는 해당 메시지를 재전송(Redelivery)합니다. 이때 무한 재시도로 인한 시스템 마비를 막기 위해 필수적인 속성입니다.
JMSXDeliveryCount(Integer):- 의미: 브로커가 해당 메시지를 컨슈머에게 전달하려고 시도한 총 횟수입니다.
- 활용법: 이 값은 생산자가 세팅하는 것이 아니라, 브로커가 메시지를 큐에서 꺼내 컨슈머로 내려보낼 때마다 1씩 자동 증가시킵니다. 컨슈머 애플리케이션은 메시지를 수신했을 때
message.getIntProperty("JMSXDeliveryCount")를 호출하여 몇 번째 재시도인지 확인할 수 있습니다. 만약 이 값이 브로커에 설정된 최대 재시도 횟수(예: 5)에 도달하면, 브로커는 해당 메시지를 DLQ(Dead Letter Queue)로 강제 이동시켜 전체 큐의 선두 차단(Head-of-Line Blocking) 현상을 방지합니다.
3. 보안 및 감사(Audit) 트레일링: JMSXUserID 및 JMSXAppID
엔터프라이즈 환경에서는 누가, 어떤 시스템에서 메시지를 발행했는지 추적(Tracing)하고 인가(Authorization)를 검증하는 작업이 매우 중요합니다.
JMSXUserID(String):- 의미: 메시지를 전송한 사용자(또는 시스템 계정)의 식별자입니다.
- 활용법: 클라이언트가 임의로 조작하는 것을 막기 위해, 브로커 설정(예: ActiveMQ의
populateJMSXUserID=true)을 통해 브로커가 직접 연결된 세션의 인증 정보를 바탕으로 덮어쓰도록 강제할 수 있습니다. 이를 통해 컨슈머는 메시지의 출처를 100% 신뢰할 수 있으며, 악의적인 메시지 발행을 차단할 수 있습니다.
JMSXAppID(String):- 의미: 메시지를 생성하고 전송한 애플리케이션의 고유 식별자입니다.
- 활용법: 여러 종류의 마이크로서비스가 단일 브로커를 공유할 때, 메시지의 발생지를 특정하거나 분산 트레이싱(Distributed Tracing) 로그를 남길 때 유용하게 활용됩니다.
4. 트랜잭션 및 타임스탬프 관련 추가 속성
상대적으로 사용 빈도는 낮지만, 특정 벤더나 복잡한 분산 트랜잭션(XA) 환경에서 활용되는 속성들입니다.
JMSXProducerTXID/JMSXConsumerTXID(String):- 메시지가 생산되거나 소비될 때 속해 있던 트랜잭션의 식별자입니다. 분산 환경에서 글로벌 트랜잭션의 롤백 및 커밋 로그를 추적하여 데이터 정합성을 감사할 때 사용됩니다.
JMSXRcvTimestamp(Long):- 생산자가 메시지를 생성한 시간(
JMSTimestamp)과 달리, 브로커가 해당 메시지를 컨슈머에게 물리적으로 '전달(Deliver)'한 시점의 타임스탬프입니다. 메시지가 큐에서 얼마나 오래 대기했는지, 네트워크 지연 시간이 얼마나 발생했는지 등 시스템 레이턴시(Latency)를 모니터링하는 지표로 활용됩니다.
JMSXState(Integer):- 브로커 내부에서 메시지의 현재 상태(Waiting, Ready, Retained 등)를 나타냅니다. 주로 브로커의 관리자 콘솔(Admin UI)이나 JMX 모니터링 툴에서 큐의 상태를 시각화할 때 내부적으로 사용됩니다.
5. JMSX 속성 사용 시의 아키텍처 설계 주의사항
- 벤더 종속성 확인: JMS 스펙은
JMSXGroupID나JMSXDeliveryCount등 일부 속성의 지원을 필수(Mandatory)로 강제하지만,JMSXUserID,JMSXAppID,JMSXProducerTXID등 상당수는 벤더의 선택(Optional) 사항입니다. 따라서 브로커를 교체할 때 해당 속성이 정상적으로 동작하는지 반드시 사전 검증해야 합니다. - 보안 속성의 무결성 보장:
JMSXUserID와 같은 보안 속성은 절대 클라이언트(생산자)의 코드를 전적으로 신뢰해서는 안 됩니다. 반드시 브로커 단에서 세션 정보를 가로채어 검증하고 주입(Populate)하는 플러그인 설정을 활성화해야 스푸핑(Spoofing) 공격을 막을 수 있습니다. - 셀렉터(Selector)와의 결합: 컨슈머는 메시지 셀렉터를 작성할 때 JMSX 속성을 일반 사용자 정의 속성처럼 조건문(
WHERE)에 사용할 수 있습니다. (예:JMSXDeliveryCount > 2). 이를 활용하면 "2번 이상 실패한 메시지만 별도로 수집하여 분석하는 전용 모니터링 컨슈머"를 라우팅 비용 없이 손쉽게 구축할 수 있습니다.
'1. 개발 > 1.8. ActiveMQ' 카테고리의 다른 글
| 만료된 메시지(Expired)를 추적하기 위한 감사(Audit) 로그 설정은? (0) | 2026.03.17 |
|---|---|
| 브로커가 메시지를 버리는 'Discard' 정책의 설정법은? (0) | 2026.03.17 |
| 메시지 본문(Body) 크기가 성능에 미치는 상관관계는? (0) | 2026.03.16 |
| 복합 헤더 속성을 이용한 라우팅 필터링 기법은? (0) | 2026.03.16 |
| 미전달 메시지(DLQ)로 보내기 전 '최대 재시도 횟수'의 기본값과 변경법은? (0) | 2026.03.16 |