브로커 수준의 'Wildcard' 지원 형식(Classic vs Artemis) 비교?
엔터프라이즈 메시징 환경에서 수많은 이벤트와 데이터를 효율적으로 라우팅하기 위해 토픽 계층화(Topic Hierarchy)와 와일드카드(Wildcard)를 활용하는 것은 필수적인 아키텍처 패턴입니다. 생산자(Producer)는 category.subcategory.item과 같이 세밀하게 주소를 분류하여 메시지를 발행하고, 소비자(Consumer)는 와일드카드를 사용하여 자신이 관심 있는 범위의 메시지만 동적으로 구독할 수 있습니다.
하지만 ActiveMQ 5.x (Classic) 버전과 차세대 아키텍처인 ActiveMQ Artemis는 기본적으로 지원하는 와일드카드 문법에 결정적인 차이가 있습니다. 마이그레이션을 수행하거나 이기종 프로토콜(AMQP, MQTT 등)을 혼용할 때 라우팅 장애를 예방하기 위해 두 브로커의 와일드카드 지원 형식을 명확히 비교하고 제어 방법을 분석합니다.

1. ActiveMQ Classic의 와일드카드 문법
ActiveMQ Classic은 오랫동안 자바 기반 엔터프라이즈 환경에서 표준처럼 사용되어 온 독자적인 와일드카드 문법을 가지고 있습니다.
- 경로 구분자 (Separator):
.(마침표) - 주소의 계층을 나눕니다. (예:
sensor.temperature.seoul)
- 단일 계층 와일드카드 (Single-level):
*(별표) - 트리 구조에서 정확히 하나의 계층(단어)과 일치합니다.
- 예시:
sensor.*.seoul을 구독하면sensor.temperature.seoul이나sensor.humidity.seoul은 수신하지만,sensor.temperature.seoul.gangnam은 수신하지 못합니다.
- 다중 계층 와일드카드 (Multi-level):
>(오른쪽 꺾쇠) - 지정된 위치부터 그 하위의 모든 계층과 일치합니다. 반드시 주소의 가장 마지막에만 위치해야 합니다.
- 예시:
sensor.temperature.>를 구독하면sensor.temperature.seoul,sensor.temperature.seoul.gangnam,sensor.temperature.busan등 하위의 모든 트리를 포괄하여 수신합니다.
2. ActiveMQ Artemis의 기본 와일드카드 문법
ActiveMQ Artemis는 AMQP(Advanced Message Queuing Protocol) 1.0 표준과 라우팅 철학을 공유하며, 와일드카드 문법 역시 AMQP의 규격을 기본값으로 채택했습니다. 이로 인해 Classic 버전 사용자들에게 가장 많은 혼란을 유발합니다.
- 경로 구분자 (Separator):
.(마침표) - Classic과 동일하게 마침표를 사용합니다.
- 단일 계층 와일드카드 (Single-level):
*(별표) - Classic과 동일하게 정확히 하나의 계층과 일치합니다.
- 다중 계층 와일드카드 (Multi-level):
#(해시/샵) - Classic의
>역할을#이 대신합니다. 하위의 모든 계층을 포괄합니다. - 예시:
sensor.temperature.#을 구독하면 하위의 모든 노드 메시지를 수신합니다.
비교 요약표
| 구분 | ActiveMQ Classic | ActiveMQ Artemis (기본값) | MQTT 프로토콜 (참고) |
|---|---|---|---|
| 계층 구분자 | . |
. |
/ |
| 단일 계층 일치 | * |
* |
+ |
| 다중 계층 일치 | > |
# |
# |
3. Artemis에서의 와일드카드 문법 커스터마이징 및 호환성 설정
Artemis의 가장 강력한 장점 중 하나는 브로커 내부의 와일드카드 라우팅 문법을 관리자가 원하는 대로 완전히 재정의(Customizing)할 수 있다는 것입니다.
만약 수백 개의 레거시 클라이언트가 소스 코드 내에 sensor.> 형태로 다중 계층 와일드카드를 하드코딩하고 있다면, 클라이언트를 수정하는 대신 Artemis 브로커의 설정을 Classic 호환 모드로 변경하여 즉각적으로 대응할 수 있습니다.
broker.xml 파일 내에서 <wildcard-addresses> 블록을 수정하여 전역 라우팅 문법을 변경합니다.
<core xmlns="urn:activemq:core">
<wildcard-addresses>
<routing-enabled>true</routing-enabled>
<delimiter>.</delimiter>
<any-words>*</any-words>
<any-descendent>></any-descendent>
</wildcard-addresses>
</core>
이렇게 설정하면 Artemis 브로커 내부의 라우팅 엔진은 > 기호를 만났을 때 이를 다중 계층 와일드카드로 인식하고, 레거시 시스템과 완벽하게 호환되는 라우팅을 수행합니다.
4. 이기종 프로토콜 환경(MQTT, AMQP)에서의 변환 매커니즘
모던 메시징 아키텍처에서는 하나의 Artemis 브로커에 JMS(자바), MQTT(IoT 기기), AMQP(마이크로서비스) 클라이언트가 동시에 접속합니다. 각 프로토콜은 고유의 와일드카드 문법을 갖습니다. (예: MQTT는 sensor/+/seoul)
Artemis는 각 프로토콜별 접속 접점인 Acceptor 레벨에서 수신된 와일드카드를 브로커의 코어(Core) 문법으로 자동 변환(Translation)하는 스마트 라우팅 기능을 내장하고 있습니다.
- IoT 기기가 MQTT 프로토콜로
sensor/temperature/#을 구독 요청합니다. - Artemis의 MQTT Acceptor는 이를 내부적으로
sensor.temperature.#(또는 브로커에 설정된 다중 계층 기호)로 치환하여 메모리 라우팅 트리에 등록합니다. - AMQP 생산자가
sensor.temperature.seoul로 메시지를 발행하면, 브로커는 정상적으로 두 클라이언트 간의 메시지를 매칭시켜 전달합니다.
5. 아키텍처 설계 시 와일드카드 남용 방지 가이드
와일드카드는 유연한 구독을 가능하게 하지만, 브로커의 성능(CPU 파싱 연산)에 직접적인 영향을 미칩니다.
- 최상위 계층 와일드카드 금지:
>또는#단독으로 구독을 시도하거나,*.temperature.#처럼 최상위(Root) 계층을 비워두는 패턴은 브로커 내의 모든 메시지를 스캔하게 만들어 심각한 성능 저하와 OOM(Out of Memory)을 유발합니다. 반드시 대분류(Domain)는 명확히 지정(sensor.*.#)해야 합니다. - 동적 목적지 생성 제한: 와일드카드 구독자가 있는 상태에서 생산자가 무작위의 고유 ID를 주소 계층에 포함하여(예:
log.info.12345,log.info.12346) 지속적으로 발행하면, 브로커 메모리에 수백만 개의 라우팅 트리가 생성되어(Address Space Exhaustion) 시스템이 마비됩니다. 변동성이 큰 식별자는 주소 계층이 아닌 메시지의 헤더(Property)나 본문에 넣고 필터(Selector)를 활용해야 합니다.
'1. 개발 > 1.8. ActiveMQ' 카테고리의 다른 글
| JMS 2.0의 'Delivery Delay'와 Classic의 'Scheduled Message' 차이는? (0) | 2026.03.19 |
|---|---|
| 'Retroactive Consumer'를 통한 과거 토픽 메시지 수신법은? (0) | 2026.03.19 |
| 'Filter'와 'Divert'를 조합한 정교한 메시지 라우팅 설계법은? (0) | 2026.03.19 |
| Artemis의 'Divert' 기능을 이용한 메시지 변환 및 복제 시나리오는? (0) | 2026.03.19 |
| 비영속성 메시지(Non-persistent)가 메모리 부족 시 디스크로 스왑되는 과정은? (0) | 2026.03.18 |