복합 헤더 속성을 이용한 라우팅 필터링 기법은?
엔터프라이즈 메시징 시스템(ActiveMQ, Artemis, Amazon MQ 등)을 구축하다 보면, 단순히 큐(Queue)나 토픽(Topic) 이름만으로 메시지를 분기하는 물리적 라우팅 방식에 한계를 느끼는 순간이 찾아옵니다. 시스템이 거대해지고 마이크로서비스(MSA) 환경이 복잡해질수록, 메시지의 페이로드(Payload)를 열어보지 않고도 메시지에 부착된 다수의 메타데이터를 조합하여 정교하게 타겟을 결정해야 하는 요구사항이 발생하기 때문입니다.
이때 활용할 수 있는 강력한 무기가 바로 '복합 헤더 속성(Composite Header Properties)을 이용한 라우팅 필터링 기법'입니다. 본 가이드에서는 표준 JMS 헤더와 사용자 정의 프로퍼티를 결합하여 다차원적인 라우팅 매트릭스를 구축하는 방법과 아키텍처적 고려사항을 상세히 해부합니다.

1. 복합 헤더 속성(Composite Header Properties)의 개념
메시지 브로커에서 필터링을 수행할 때, 단일 조건(예: region = 'SEOUL')만 사용하는 경우는 드뭅니다. 실무에서는 브로커가 제공하는 표준 JMS 헤더(JMS Headers)와 생산자가 임의로 주입한 사용자 정의 프로퍼티(Custom Properties)를 SQL-92 문법의 논리 연산자(AND, OR, NOT)로 엮어 복합적인 필터링 조건을 생성합니다.
- 표준 헤더 활용: 메시지의 생성 시간(
JMSTimestamp), 만료 시간(JMSExpiration), 우선순위(JMSPriority), 메시지 타입(JMSType) 등 브로커가 기본적으로 인지하는 속성입니다. - 사용자 정의 프로퍼티 활용: 비즈니스 도메인에 특화된 데이터입니다. 예를 들어
tenantId(SaaS 고객사 식별자),deviceType(센서 종류),transactionAmount(결제 금액) 등을 메시지 헤더에 Map 형태로 추가할 수 있습니다.
이 두 가지를 결합하면 다음과 같은 복합 필터링 구문(Selector)이 완성됩니다.
(JMSPriority > 5 AND region = 'US' AND deviceType IN ('IOS', 'ANDROID')) OR (tenantId = 'VIP_001')
2. 메시지 브로커별 라우팅 필터링 구현 메커니즘
복합 헤더를 이용한 필터링은 사용하는 브로커의 아키텍처에 따라 구현 방식이 다릅니다. 차세대 브로커인 ActiveMQ Artemis를 기준으로 서버 측 라우팅 필터링(Server-side Routing Filtering) 메커니즘을 살펴보겠습니다.
A. Artemis의 <filter> 설정을 통한 정적 라우팅
Artemis는 클라이언트(Consumer)가 필터를 걸고 들어오는 방식뿐만 아니라, 브로커 내부의 주소(Address)와 큐(Queue) 매핑 단계에서 원천적으로 메시지를 차단하거나 분기하는 강력한 기능을 제공합니다. broker.xml 설정 파일에 복합 조건을 명시할 수 있습니다.
<addresses>
<address name="global.telemetry.address">
<multicast>
<queue name="critical.us.queue">
<filter string="region = 'US' AND JMSPriority >= 8"/>
</queue>
<queue name="error.log.queue">
<filter string="JMSType = 'ERROR' AND errorCode IS NOT NULL"/>
</queue>
<queue name="vip.mobile.payment.queue">
<filter string="tenantTier = 'VIP' AND deviceType LIKE 'MOBILE_%'"/>
</queue>
</multicast>
</address>
</addresses>
동작 원리: 생산자는 오직 global.telemetry.address라는 단일 진입점으로 모든 메시지를 쏟아냅니다. 브로커는 내부 라우터(Router)를 통해 각 메시지의 헤더를 분석하고, filter 조건에 완벽히 부합하는 큐에만 메시지를 복사(Routing)하여 적재합니다. 조건에 맞지 않는 큐에는 아예 메시지가 들어가지 않으므로, 컨슈머 측의 불필요한 스캔 작업이 원천 차단됩니다.
3. 실무 적용 시나리오 (Use Cases)
복합 헤더 필터링은 다음과 같은 엔터프라이즈 아키텍처 패턴을 구현할 때 핵심적인 역할을 합니다.
- 멀티 테넌트(Multi-Tenant) 데이터 격리:
하나의 거대한 통합 메시징 클러스터를 운영하는 SaaS 플랫폼에서, 메시지 헤더에tenantId와subscriptionPlan(예: BASIC, PRO, ENTERPRISE)을 주입합니다. 엔터프라이즈 등급의 고객 데이터는 전용 고성능 큐로 라우팅하고, 일반 고객 데이터는 공용 큐로 라우팅하여 SLA(서비스 수준 협약)를 차등 보장할 수 있습니다. - 버전 기반 카나리 배포 (Canary Release Routing):
API 게이트웨이나 생산자 측에서 메시지 헤더에apiVersion = 'v2.0'을 추가합니다. 브로커에서는 특정 비율의 트래픽이나 특정 테스트 사용자 그룹(isBetaUser = TRUE)의 메시지만 신규 배포된 v2.0 컨슈머 큐로 흘려보내고, 나머지는 기존 v1.0 큐로 유지하는 무중단 배포 및 A/B 테스트 파이프라인을 구축할 수 있습니다. - 우선순위 역전 방지 및 데드라인 스케줄링:
특정 시간 안에 반드시 처리되어야 하는 메시지에JMSTimestamp와timeToLive커스텀 속성을 부여합니다. 이를 바탕으로 긴급한 트랜잭션만 필터링하여 스레드 풀이 넉넉한 전담 처리 워커(Worker) 그룹으로 즉시 바이패스시키는 QoS(Quality of Service) 제어가 가능합니다.
4. 아키텍처 설계 시 주의사항 및 성능 최적화 (Best Practices)
복합 필터링은 무한한 유연성을 제공하지만, 조건이 길어질수록 브로커의 CPU 연산 부하가 기하급수적으로 증가합니다. 따라서 성능과 유연성 사이의 절충점을 찾는 것이 매우 중요합니다.
- 물리적 라우팅과 논리적 필터링의 하이브리드 설계:
가장 나쁜 안티 패턴은 하나의 거대한 글로벌 주소(Address)에 수천 개의 큐를 매핑하고 모든 것을<filter>구문으로만 분기하는 것입니다. 대분류(예: 국가, 대도메인)는 토픽 계층화(Topic Hierarchy, 예:telemetry.us,telemetry.eu)를 통해 물리적으로 분리하여 브로커의 파싱 부담을 덜어주고, 중분류 이하의 세밀한 조건(예: 우선순위, VIP 여부)만 복합 헤더 필터링으로 처리하는 투트랙(Two-track) 전략을 구사해야 합니다. - 자료형 일치 및 단순화:
필터 구문 내에서 자료형 변환이 일어나지 않도록 주의해야 합니다. 생산자가priority를 숫자형(Integer)으로 넣었다면 필터에서도 숫자 연산을 해야 하며, 이를 문자열과 비교하려 하면 브로커 내부에서 형 변환 오버헤드가 발생하거나 조건이 매칭되지 않는 버그가 생깁니다. 또한, 값비싼 정규식(LIKE) 연산보다는 명확한 동등 비교(=,IN) 위주로 필터를 단순화해야 합니다.
5. 요약 및 결론
복합 헤더 속성을 이용한 라우팅 필터링은 생산자와 소비자 간의 결합도를 극단적으로 낮추어주는 강력한 패턴입니다. 생산자는 목적지를 알 필요 없이 자신의 상태를 명확히 표현하는 메타데이터(헤더)만 충실히 달아서 던지면 되고, 인프라스트럭처(브로커)가 비즈니스 규칙에 따라 트래픽을 지능적으로 통제합니다.
이러한 선언적 라우팅(Declarative Routing) 기법을 아키텍처에 적절히 녹여낸다면, 소스 코드의 수정 없이 인프라 설정 변경만으로도 비즈니스 요구사항의 변화에 유연하게 대응할 수 있는 견고한 메시징 플랫폼을 완성할 수 있습니다.
'1. 개발 > 1.8. ActiveMQ' 카테고리의 다른 글
| JMS 전용 속성(JMSX로 시작하는 속성)의 종류와 활용법은? (0) | 2026.03.16 |
|---|---|
| 메시지 본문(Body) 크기가 성능에 미치는 상관관계는? (0) | 2026.03.16 |
| 미전달 메시지(DLQ)로 보내기 전 '최대 재시도 횟수'의 기본값과 변경법은? (0) | 2026.03.16 |
| 독점 컨슈머(Exclusive Consumer)의 우선순위 결정 방식은? (0) | 2026.03.16 |
| 'JMSXGroupID'를 이용한 순서 보장의 한계는? (1) | 2026.03.15 |