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

'Async Send' 사용 시 브로커의 승인(Ack) 없이 보낼 수 있는 최대 양은?

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

'Async Send' 사용 시 브로커의 승인(Ack) 없이 보낼 수 있는 최대 양은?

엔터프라이즈 메시징 아키텍처에서 시스템의 초당 메시지 처리량(Throughput)을 극한으로 끌어올리기 위해 개발자들이 가장 먼저 손을 대는 옵션 중 하나가 바로 '비동기 전송(UseAsyncSend)' 기능입니다.

기본적으로 메시지 브로커는 데이터 유실을 막기 위해 프로듀서(Producer)가 보낸 영속성(Persistent) 메시지를 디스크에 안전하게 기록한 뒤에야 "잘 받았다"는 승인(ACK, Acknowledgment) 신호를 클라이언트에게 반환합니다. 클라이언트는 이 ACK를 받을 때까지 스레드를 멈추고 대기(Blocking)해야 하므로 극심한 네트워크 및 디스크 I/O 지연을 겪게 됩니다. 비동기 전송은 이 대기 시간을 없애고 메시지를 쏘고 바로 다음 로직을 실행하는 'Fire and Forget' 방식을 가능하게 합니다.

하지만 프로듀서가 브로커의 상태를 무시하고 무한정 메시지를 쏟아붓는다면 브로커의 메모리는 순식간에 터져버릴 것입니다. 브로커를 보호하면서도 비동기의 속도를 누리기 위해, 아키텍처 내부에는 승인 없이 보낼 수 있는 데이터의 '최대 한계선'이 존재합니다. 이 가이드에서는 비동기 전송 시 메시지 흐름을 통제하는 윈도우 사이즈(Window Size)의 원리와 최적화 튜닝 방법을 상세히 해부합니다.


1. 비동기 전송의 브레이크 장치: 프로듀서 윈도우 사이즈(Producer Window Size)

결론부터 말씀드리면, 브로커의 ACK 없이 프로듀서가 네트워크로 밀어낼 수 있는 메시지의 최대 양은 '개수(Count)'가 아니라 '바이트(Byte) 크기'로 결정되며, 이를 프로듀서 윈도우 사이즈라고 부릅니다.

비동기 전송이 활성화되면 클라이언트(프로듀서) 내부에는 설정된 크기만큼의 가상 메모리 공간(Window)이 할당됩니다.

  • 동작 원리: 프로듀서가 메시지를 보낼 때마다, 클라이언트 라이브러리는 전송된 메시지의 바이트 크기만큼 윈도우의 남은 공간을 차감합니다.
  • 한계 도달 시 블로킹: 브로커로부터 ACK를 받지 못한 상태에서 계속 메시지를 전송하다가, 누적된 전송 바이트가 윈도우 사이즈의 최대치에 도달하면 클라이언트의 send() 메서드는 더 이상 비동기로 동작하지 않고 그 자리에서 멈춰버립니다(Blocking).
  • 윈도우 공간 회수: 이후 브로커가 디스크 쓰기를 마치고 그동안 밀려있던 메시지들에 대한 일괄 승인(ProducerAck)을 클라이언트로 보내면, 클라이언트는 승인받은 메시지의 바이트만큼 윈도우 공간을 다시 회수하여 비워줍니다. 공간이 생기면 멈춰있던 send() 메서드가 풀리며 다시 전송을 재개합니다.

이러한 메커니즘을 통신 공학에서는 '슬라이딩 윈도우(Sliding Window) 기반의 흐름 제어(Flow Control)'라고 부릅니다.


2. 환경별 윈도우 사이즈 설정과 기본값

ActiveMQ Classic과 차세대 버전인 Artemis는 이 윈도우 사이즈를 제어하는 파라미터 이름과 적용 방식에 약간의 차이가 있습니다.

A. ActiveMQ Classic 환경

ActiveMQ Classic에서 영속성 메시지를 비동기로 보내려면 연결 URI에 옵션을 명시해야 합니다.
useAsyncSend를 참으로 설정하더라도, 프로듀서 윈도우 사이즈를 명시적으로 제한하지 않으면 기본적으로 브로커의 메모리 한계(Memory Usage Limit)를 감지하는 별도의 흐름 제어(Producer Flow Control)에 전적으로 의존하게 됩니다. 네트워크 단에서 클라이언트의 전송량을 정확히 통제하려면 커넥션 파라미터에 바이트 단위로 윈도우 크기를 강제해야 합니다.
(예: tcp://localhost:61616?jms.useAsyncSend=true&jms.producerWindowSize=1048576) 위 예시는 1메가바이트(1048576 바이트)를 한계선으로 설정한 것입니다.

B. ActiveMQ Artemis 환경

Artemis는 아키텍처가 더욱 발전하여 비동기 전송과 흐름 제어가 더욱 정교하게 통합되어 있습니다.
Artemis 커넥션 팩토리(Connection Factory) 설정에서는 confirmation-window-size (또는 코어 API의 경우 producer-window-size)라는 이름으로 이 옵션을 제공합니다.
클라이언트가 메시지를 전송하며 소비한 바이트가 이 윈도우 사이즈에 도달하면, 브로커가 크레딧(Credit)을 다시 부여해 줄 때까지 클라이언트 측 전송 스레드가 일시 정지됩니다. 기본값은 환경에 따라 다르나 보통 수십 메가바이트 수준으로 넉넉하게 잡혀 있어, 대용량 트래픽 환경에서는 이 값을 반드시 비즈니스 요구사항에 맞게 튜닝해야 합니다.


3. 최대 전송량(Window Size) 설정의 트레이드오프

이 윈도우 사이즈를 얼마로 설정하느냐에 따라 시스템의 운명이 극명하게 갈립니다. 인프라 아키텍트는 다음 두 가지 극단적인 상황 사이에서 최적의 균형을 찾아야 합니다.

사례 1: 윈도우 사이즈를 너무 작게 설정했을 때 (예: 10킬로바이트)
메시지 하나의 크기가 2킬로바이트라면, 프로듀서는 고작 5개의 메시지를 쏘고 나서 윈도우 공간이 바닥납니다. 브로커가 이 5개에 대한 ACK를 줄 때까지 프로듀서는 블로킹됩니다. 이는 사실상 매번 ACK를 기다리는 동기 전송(Sync Send)과 다를 바가 없게 되며, 비동기 전송을 켠 의미가 완전히 퇴색됩니다. 네트워크 대역폭을 전혀 활용하지 못하고 초당 처리량(TPS)이 바닥을 치게 됩니다.

사례 2: 윈도우 사이즈를 너무 크게 설정했을 때 (예: 1기가바이트)
윈도우 사이즈를 아득히 크게 잡아두면, 프로듀서는 브로커의 상태와 무관하게 1기가바이트 분량의 메시지를 네트워크와 브로커의 수신 버퍼를 향해 무자비하게 쏟아냅니다.
이 경우 브로커 서버의 CPU와 메모리는 들어오는 메시지를 파싱하고 라우팅하느라 과부하에 빠지게 됩니다. 더 끔찍한 것은, 브로커가 미처 디스크에 쓰지 못한 상태에서 브로커 서버의 전원이 차단되거나 네트워크 케이블이 단절되는 경우입니다. 클라이언트 입장에서는 1기가바이트에 달하는 수백만 건의 메시지가 "이미 전송된 것"으로 취급되어 메모리에서 지워졌지만, 실제 브로커 디스크에는 존재하지 않는 거대한 데이터 증발(Data Loss) 사태를 맞이하게 됩니다.


4. 아키텍처 최적화 튜닝 가이드 (Best Practices)

안전하고 빠른 비동기 전송 파이프라인을 구축하려면 다음과 같은 튜닝 기준을 적용해야 합니다.

  1. 지연 시간(Latency)과 대역폭의 곱 (BDP 기반 산정):
    가장 이상적인 윈도우 사이즈는 프로듀서와 브로커 간의 네트워크 왕복 시간(RTT) 동안 전송할 수 있는 데이터의 총량입니다. 네트워크가 빠르고 지연 시간이 짧은 로컬망이라면 수 메가바이트 수준으로도 충분한 성능을 뽑아낼 수 있습니다. 반면 해외 리전을 가로지르는 등 지연 시간이 긴 네트워크 환경이라면 윈도우 사이즈를 수십 메가바이트 이상으로 넉넉하게 늘려주어야 대역폭을 낭비 없이 활용할 수 있습니다.
  2. 평균 메시지 크기와 트랜잭션 묶음 단위 고려:
    단일 메시지 크기가 수 메가바이트 단위로 큰 대용량 데이터(Large Message)를 주로 다룬다면 윈도우 사이즈 역시 비례해서 크게 잡아주어야 블로킹 횟수를 줄일 수 있습니다. 반면 수백 바이트 단위의 작고 민감한 금융 트랜잭션이라면 윈도우 사이즈를 좁혀 데이터 유실의 피해 범위를 최소화하는 방어적인 설계가 필요합니다.
  3. 브로커 측 메모리 한계와의 동기화:
    클라이언트 측의 윈도우 사이즈 총합이 브로커 서버가 감당할 수 있는 큐의 최대 메모리 임계값을 초과해서는 안 됩니다. 100대의 프로듀서 서버가 각각 10메가바이트의 윈도우를 가지고 쏘아댄다면, 브로커는 순간적으로 1기가바이트의 트래픽 폭탄을 맞게 됩니다. 프로듀서의 수량과 브로커의 힙 메모리를 종합적으로 계산하여 제한을 두어야 합니다.

결론적으로 비동기 전송 기능은 마법의 성능 향상 버튼이 아닙니다. 이 기능의 진정한 가치는 클라이언트와 브로커 사이에 고무줄처럼 늘어나고 줄어드는 완충 공간인 '윈도우 사이즈'를 얼마나 정교하게 조율하느냐에 달려 있습니다. 브로커의 수용 능력과 네트워크 환경을 면밀히 분석하여 가장 완벽한 데이터 한계선을 설정하시기 바랍니다.

반응형