본문 바로가기
1. 개발/1.8. ActiveMQ

브로커 간 메시지 전달 시 'Hop Count' 제한 방법은?

by 엉짱 2026. 3. 17.
반응형

브로커 간 메시지 전달 시 'Hop Count' 제한 방법은?

대규모 분산 시스템에서는 단일 메시지 브로커의 성능 한계를 극복하고 고가용성(HA)을 확보하기 위해 여러 대의 브로커를 엮어 클러스터(Cluster)나 네트워크(Network of Brokers)를 구성합니다. 이때 브로커 간에 메시지가 전달되도록 라우팅 경로를 설정하게 되는데, 잘못된 구성은 메시지가 목적지를 찾지 못하고 브로커 사이를 무한히 맴도는 무한 라우팅 루프(Infinite Routing Loop)를 유발할 수 있습니다.

이를 방지하고 메시지의 이동 범위를 통제하는 핵심 메커니즘이 바로 Hop Count(브로커 도약 횟수) 제한입니다. 메시지가 거칠 수 있는 최대 브로커 노드의 수를 제한하는 이 기능을 ActiveMQ Classic과 Artemis 환경에서 어떻게 설정하고 통제하는지 상세히 분석합니다.


1. Hop Count(Network TTL)의 개념과 루프 방지 원리

네트워크 통신에서 패킷의 수명을 결정하는 TTL(Time-To-Live)과 동일한 개념입니다. 메시지가 A 브로커에서 B 브로커로 넘어갈 때마다 내부적인 Hop 카운트가 1씩 감소(또는 증가)하며, 지정된 최대 횟수에 도달하면 브로커는 해당 메시지를 더 이상 다른 브로커로 전달(Forwarding)하지 않고 폐기하거나 로컬 큐에만 보관합니다.

  • 루프 발생 시나리오: A, B, C 세 대의 브로커가 서로 모두 연결된 Mesh 토폴로지에서 컨슈머가 없을 때, 메시지가 A $\rightarrow$ B $\rightarrow$ C $\rightarrow$ A 형태로 끝없이 회전하며 네트워크 대역폭과 브로커의 CPU/메모리를 고갈시킵니다.
  • 해결책: Hop Count를 적절히 제한하고, 브로커 내부적으로 이미 거쳐 간 브로커의 ID를 추적하여 동일한 브로커로 메시지가 되돌아오는 것을 원천 차단합니다.

2. ActiveMQ Classic의 Network TTL 설정법

ActiveMQ 5.x 버전에서는 'Network of Brokers'를 구성할 때 activemq.xml 파일의 <networkConnectors> 블록을 사용합니다. 여기서 Hop Count는 networkTTL이라는 속성으로 제어됩니다.

  • 기본값: 1 (즉, 메시지는 최초 생성된 브로커에서 다른 브로커로 단 한 번만 넘어갈 수 있습니다.)
<networkConnectors>
   <networkConnector name="linkToBrokerB" 
                     uri="static:(tcp://brokerB:61616)" 
                     networkTTL="2"
                     duplex="true"
                     decreaseNetworkConsumerPriority="true" />
</networkConnectors>

주요 속성 분석:

  • networkTTL="2": 메시지가 A $\rightarrow$ B $\rightarrow$ C 까지 도달할 수 있음을 의미합니다.
  • decreaseNetworkConsumerPriority="true": 로컬 브로커에 연결된 컨슈머가 원격 브로커에 연결된 컨슈머보다 우선순위를 갖게 하여, 불필요한 네트워크 홉을 최소화합니다.
  • conduitSubscriptions: 여러 컨슈머가 있더라도 원격 브로커로 메시지를 하나만 보내어 네트워크 트래픽을 줄이는 기능과 Hop Count가 결합하여 동작합니다.

3. ActiveMQ Artemis의 Max Hops 설정법

차세대 브로커인 Artemis는 대칭형/비대칭형 클러스터링 구조를 가지며, broker.xml 파일의 <cluster-connection> 설정을 통해 Hop Count를 제어합니다. 속성명은 max-hops를 사용합니다.

  • 기본값: 1
<cluster-connections>
   <cluster-connection name="my-cluster">
      <address>jms</address>
      <connector-ref>netty-connector</connector-ref>
      <max-hops>1</max-hops>
      <discovery-group-ref discovery-group-name="my-discovery-group"/>
   </cluster-connection>
</cluster-connections>

Artemis의 향상된 내부 루프 추적 메커니즘:
Artemis는 단순히 숫자만 줄이는 것이 아니라, 메시지가 브로커를 통과할 때마다 내부 헤더에 통과한 브로커의 고유 UUID를 기록합니다. max-hops가 2 이상으로 설정되어 있더라도, 라우터는 다음 타겟 브로커의 UUID가 이미 메시지 헤더에 기록되어 있다면 해당 라우팅을 거부하여 루핑을 철저히 차단합니다.


4. 네트워크 토폴로지별 적정 Hop Count 가이드

브로커 인프라를 어떤 형태로 구성하느냐에 따라 적절한 Hop Count 설정값이 달라집니다.

  1. Hub-and-Spoke (중앙 집중형):
    중앙에 핵심 브로커(Hub)가 있고 여러 지점 브로커(Spoke)가 중앙에만 연결된 형태입니다. 지점 간 직접 통신이 없으므로 networkTTL 또는 max-hops1로 설정하는 것이 안전하고 충분합니다.
  2. Linear / Daisy Chain (선형 연결):
    브로커 A $\rightarrow$ B $\rightarrow$ C 형태로 일렬로 연결된 구조입니다. A에서 발행된 메시지를 C에 연결된 컨슈머가 처리해야 한다면, 최소한 2 이상의 Hop Count가 필요합니다.
  3. Mesh (완전/부분 망형):
    모든 브로커가 서로 거미줄처럼 연결된 고가용성 구조입니다. 이 경우 어느 브로커에서 발행하든 타겟 브로커와 1:1로 직접 연결되어 있으므로, 무조건 최단 거리로 전달되도록 Hop Count를 1로 강제해야 합니다. 이를 초과하면 메시지가 빙빙 돌며 심각한 네트워크 I/O 병목을 유발합니다.

5. 아키텍처 설계 시 주의사항

Hop Count를 단순히 늘리는 것은 메시지 도달 범위를 넓혀주지만, 시스템 전체의 처리량(Throughput)을 심각하게 저하시키는 원인이 됩니다.

메시지가 브로커를 하나 건너뛸 때마다 디스크 쓰기(Persistence), 메모리 할당, 네트워크 직렬화 연산이 중복해서 발생합니다. 따라서 networkTTL 값을 2 이상으로 설정해야만 하는 아키텍처라면, 초기 브로커 네트워크 토폴로지 설계 자체가 비효율적으로 구성되었을 확률이 높습니다. 가급적 Mesh 형태나 로드밸런서(L4/L7)를 브로커 앞단에 두어 프로듀서와 컨슈머가 클러스터 내 어느 브로커에 접속하든 1 Hop 안에 메시지 교환이 완료되도록 인프라를 평탄화(Flattening)하는 것이 최상의 설계입니다.

반응형