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

'Failover Transport' 주소에서 'randomize=false' 설정의 중요성은?

by 엉짱 2026. 4. 9.
반응형

'Failover Transport' 주소에서 'randomize=false' 설정의 중요성은?

엔터프라이즈 환경에서 메시지 브로커(ActiveMQ 등)의 고가용성(HA)을 구축할 때, 서버 인프라를 Master-Slave로 이중화하는 것만큼이나 중요한 것이 바로 '클라이언트 애플리케이션의 연결 지속성'입니다. 마스터 브로커가 다운되었을 때 클라이언트가 에러를 뿜으며 죽지 않고, 스스로 슬레이브 브로커를 찾아가 연결을 맺도록 유도하는 클라이언트 측의 핵심 기술이 바로 Failover Transport입니다.

일반적으로 클라이언트의 접속 URI는 failover:(tcp://broker1:61616,tcp://broker2:61616)와 같은 형태로 작성됩니다. 하지만 이 단순해 보이는 문자열 내부에는, 시스템의 장애 복구 시간(MTTR)과 접속 지연 시간(Connection Latency)을 극단적으로 좌우하는 숨겨진 핵심 파라미터가 존재합니다. 바로 오늘 다룰 randomize 옵션입니다.

이 가이드에서는 페일오버의 기본 동작 방식이 인프라에 미치는 함정을 해부하고, randomize=false 설정이 왜 Master-Slave 아키텍처와 다중 데이터센터 환경에서 절대적인 필수 요건인지 상세히 분석합니다.


1. 기본값(Default)의 함정: 왜 'randomize=true'인가?

ActiveMQ 클라이언트 라이브러리(JMS)를 사용할 때 페일오버 URI에 아무런 옵션을 주지 않으면, 브로커는 내부적으로 randomize=true를 기본값으로 적용합니다.

동작 원리: 클라이언트 애플리케이션이 구동되어 브로커와 최초 커넥션을 맺거나, 장애로 인해 재연결(Reconnect)을 시도할 때, URI 목록에 있는 브로커 주소들(broker1, broker2) 중 '무작위(Random)'로 하나를 뽑아서 연결을 시도합니다.

설계의 의도:
이 기능은 여러 대의 브로커가 모두 살아서 트래픽을 분산 처리하는 'Active-Active (Network of Brokers)' 아키텍처를 위해 설계되었습니다. 수백 대의 클라이언트가 동시에 켜질 때 특정 브로커에 트래픽이 쏠리는 것을 방지하고, 로드 밸런서 없이도 클라이언트 단에서 자체적인 부하 분산(Load Balancing)을 수행하도록 유도하기 위함입니다.


2. Master-Slave 아키텍처와의 치명적인 불협화음

문제는 현대 엔터프라이즈 인프라의 90% 이상이 채택하고 있는 공유 스토리지 기반의 Master-Slave (Active-Standby) 구조에서 발생합니다.

Master-Slave 구조에서는 오직 마스터 노드만이 포트를 열고 정상적인 커넥션을 수립할 수 있습니다. 대기 중인 슬레이브 노드는 파일 락(Lock)이나 DB 락을 얻지 못했기 때문에, 클라이언트가 연결을 시도하더라도 이를 즉각 거부(Connection Refused)하거나 무응답 상태로 대기합니다.

'randomize=true'가 빚어내는 재앙:

  1. 애플리케이션(클라이언트)이 재시작됩니다.
  2. 클라이언트는 50퍼센트의 확률로, 하필이면 현재 대기 중인 슬레이브 노드(broker2)를 무작위로 골라 접속을 시도합니다.
  3. 슬레이브 노드는 연결을 거부합니다.
  4. 클라이언트는 접속 실패로 간주하고 내부의 백오프(Back-off) 타이머를 돌리며 일정 시간(수 밀리초~수 초)을 대기합니다.
  5. 대기 후 다시 무작위로 노드를 고릅니다. 운이 나쁘면 또 슬레이브를 고를 수 있습니다.

결과적으로 마스터 노드는 멀쩡히 살아있는데도 불구하고, 애플리케이션이 스스로 엉뚱한 문을 두드리느라 최초 기동 시간이나 페일오버 복구 시간이 불필요하게 지연되는 치명적인 비효율이 발생합니다.


3. 'randomize=false'의 동작 원리와 아키텍처 최적화

이러한 불확실성을 완벽하게 제거하고 예측 가능한 접속 파이프라인을 구축하는 스위치가 바로 randomize=false 옵션입니다.

동작 원리 (순차적 접근 메커니즘):
이 옵션이 활성화되는 순간, 클라이언트의 무작위 선택 알고리즘은 꺼집니다. 대신 괄호 안에 나열된 URI의 '물리적인 순서(Index)'를 엄격하게 따르기 시작합니다.
failover:(tcp://broker1:61616,tcp://broker2:61616)?randomize=false

  1. 클라이언트는 무조건 리스트의 첫 번째인 broker1에 연결을 시도합니다.
  2. broker1이 죽어있을 경우에만 차순위인 broker2로 넘어갑니다.
  3. 끝까지 실패하면 다시 처음(broker1)으로 돌아와 재시도를 반복합니다.

도입 효과:
인프라 엔지니어가 평소에 마스터 역할을 수행하는 주력 서버(Primary Node)를 리스트의 맨 앞에 배치해 두면, 클라이언트는 기동되자마자 단 1밀리초의 낭비 없이 정확히 마스터 서버를 찾아내어 즉각적인 커넥션을 맺습니다. 장애 발생 후 락(Lock)이 슬레이브로 넘어가 broker2가 마스터로 승격한 경우에도, broker1의 실패를 확인한 후 즉시 broker2로 부드럽게 넘어가므로 복구 지연 시간(Recovery Latency)이 극단적으로 단축됩니다.


4. 재해 복구(DR) 및 다중 데이터센터 라우팅의 필수 조건

randomize=false의 진정한 가치는 단순히 서버 두 대를 묶어놓은 로컬 HA를 넘어, 물리적으로 격리된 다중 데이터센터(IDC) 기반의 재해 복구(DR) 환경을 설계할 때 빛을 발합니다.

  • Primary IDC (서울) 노드: broker-seoul-1, broker-seoul-2
  • DR IDC (부산) 노드: broker-busan-1, broker-busan-2

서울 IDC 내의 애플리케이션은 평상시 무조건 서울 내부에 있는 브로커와 통신해야 합니다. 부산의 브로커와 통신하면 전용선 네트워크 구간을 건너뛰어야 하므로 심각한 네트워크 지연 시간(RTT 증가)과 대역폭 낭비가 발생합니다.

만약 randomize=true로 되어 있다면, 서울의 애플리케이션이 부팅될 때 랜덤하게 부산의 브로커에 붙어버리는 끔찍한 네트워크 횡단 교차(Cross-talk) 통신이 발생합니다.

이를 완벽하게 통제하려면 접속 URI를 다음과 같이 강제해야 합니다.
failover:(tcp://broker-seoul-1,tcp://broker-seoul-2,tcp://broker-busan-1,tcp://broker-busan-2)?randomize=false

이 설정 하나만으로 복잡한 글로벌 L4/GSLB 스위치 없이도 완벽한 토폴로지 라우팅이 완성됩니다. 클라이언트는 무조건 가까운 서울의 1번, 2번 브로커를 찔러봅니다. 서울 IDC 전체에 정전이 발생하여 두 노드가 모두 죽었을 때만, 최후의 보루로 부산 IDC의 브로커로 넘어가는 'Active-Standby 데이터센터 자동 페일오버' 규칙이 클라이언트 레벨에서 우아하게 구현되는 것입니다.


5. 프로덕션 환경을 위한 올바른 URI 설정 가이드 (Best Practices)

클라이언트의 영속성과 예측 가능성을 극대화하기 위해, 실무 환경에서는 randomize=false와 함께 백오프(Back-off) 및 타임아웃 관련 파라미터를 조합하여 사용하는 것이 모범 사례입니다.

failover:(tcp://master-node:61616,tcp://slave-node:61616)?randomize=false&timeout=3000&maxReconnectAttempts=-1&initialReconnectDelay=100
  • randomize=false: 무조건 첫 번째 나열된 주소부터 순차적으로 시도하여 접속 지연을 제거합니다.
  • timeout=3000: 특정 노드에 접속을 시도했을 때, 네트워크 방화벽 문제 등으로 무한정 행(Hang)이 걸리는 것을 막기 위해 3초 안에 응답이 없으면 즉시 다음 순번의 브로커로 넘어가도록 강제합니다.
  • maxReconnectAttempts=-1: 브로커 클러스터 전체가 내려갔더라도 클라이언트 애플리케이션이 에러를 뿜으며 종료되지 않고, 무한히(-1) 재연결을 시도하며 백그라운드에서 인프라의 회복을 기다리도록 만듭니다.

결론적으로 'Failover Transport'에서의 randomize 설정은 단순히 주소를 섞을지 말지를 결정하는 편의 기능이 아닙니다. 엔터프라이즈 인프라의 네트워크 토폴로지와 Master-Slave 아키텍처의 의도를 클라이언트 애플리케이션에게 정확하게 주입하여, 어떠한 장애 상황에서도 가장 빠르고 논리적인 복구 경로를 찾아가게 만드는 아키텍트의 강력한 통제 수단입니다.

반응형