브로커가 프로듀서를 차단하는 'Usage Manager'의 임계치 설정법은?
엔터프라이즈 아키텍처에서 메시지 브로커를 운영할 때 직면하는 가장 큰 위협은 컨슈머(Consumer)의 처리 속도가 느려진 상태에서 프로듀서(Producer)가 엄청난 양의 메시지를 쏟아내는 '빠른 생산자(Fast Producer)' 현상입니다. 이 상태가 지속되면 브로커의 메모리와 디스크 공간이 순식간에 고갈되어 전체 시스템이 다운되는 치명적인 장애로 이어집니다.
이를 방지하기 위해 브로커는 내부 자원(메모리, 디스크)의 사용량을 실시간으로 감시하고, 설정된 한계치에 도달하면 프로듀서의 데이터 전송을 물리적으로 차단하는 생산자 흐름 제어(Producer Flow Control) 메커니즘을 가동합니다.
이 제어의 중심에서 자원 임계치를 관리하는 시스템이 바로 ActiveMQ Classic의 Usage Manager (System Usage)와 Artemis의 Address Settings입니다. 브로커가 스스로를 보호하기 위해 프로듀서를 어떻게 차단하고, 각 자원의 한계치를 어떻게 설정해야 하는지 상세히 해부합니다.

1. 브로커의 3대 핵심 자원과 차단 원리
메시지 브로커가 관리하는 핵심 물리 자원은 크게 세 가지로 나뉩니다. 이 중 단 하나라도 임계치에 도달하면 브로커는 즉시 해당 자원을 사용하는 프로듀서의 트래픽을 차단합니다.
- 메모리 (Memory Usage): 브로커의 JVM 힙(Heap) 메모리 내에 활성화되어 있는 메시지들의 총용량입니다. 가장 빠르게 고갈되며 빈번하게 프로듀서 차단을 유발하는 요인입니다.
- 영구 저장소 (Store Usage): KahaDB나 저널(Journal) 파일 등 영속성(Persistent) 메시지가 저장되는 물리적 디스크 공간의 한계치입니다.
- 임시 저장소 (Temp Usage): 비영속성(Non-persistent) 메시지가 메모리 부족으로 인해 페이징(Paging)될 때 사용하는 임시 디스크 공간의 한계치입니다.
2. ActiveMQ Classic의 'System Usage' 설정법
ActiveMQ 5.x 버전에서는 activemq.xml 파일 내의 <systemUsage> 블록을 통해 브로커 전체(Global)의 자원 임계치를 설정합니다.
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
동작 메커니즘:
위 설정에서 KahaDB 디스크 사용량이 100GB에 도달하면, 브로커는 영속성 메시지를 보내는 모든 프로듀서의 send() 요청 처리를 중단하고 대기(Block) 상태로 만듭니다. 반면, 메모리만 70%에 도달했다면 메모리를 소비하는 프로듀서만 차단되고, 디스크로 바로 기록되는 작업은 계속 진행될 수 있습니다.
3. ActiveMQ Artemis의 페이징 및 차단 정책 설정법
차세대 브로커인 Artemis는 자원 제어를 글로벌 레벨과 주소(큐) 레벨로 더욱 정교하게 분리했습니다. broker.xml 파일에서 설정합니다.
A. 글로벌 메모리 제한 (Global Max Size)
브로커가 사용할 수 있는 전체 최대 메모리를 지정합니다. 지정하지 않으면 기본적으로 JVM 최대 메모리의 절반을 사용합니다.
<core xmlns="urn:activemq:core">
<global-max-size>2147483648</global-max-size> </core>
B. 주소별 임계치 및 차단 정책 (Address Full Policy)
Artemis의 가장 강력한 기능은 특정 큐가 가득 찼을 때 브로커가 프로듀서에게 어떤 행동을 취할지 명시적으로 결정할 수 있다는 점입니다.
<address-settings>
<address-setting match="critical.orders.#">
<max-size-bytes>52428800</max-size-bytes>
<address-full-policy>BLOCK</address-full-policy>
</address-setting>
</address-settings>
4. 프로듀서 차단 방식의 차이: BLOCK vs FAIL
임계치에 도달했을 때 브로커가 프로듀서를 막는 방식은 애플리케이션 아키텍처에 엄청난 영향을 미칩니다.
- BLOCK (대기 상태로 차단):
- 동작: 프로듀서 애플리케이션이
producer.send()를 호출하는 순간, 브로커는 응답(ACK)을 주지 않습니다. 컨슈머가 메시지를 소비하여 큐에 빈자리가 생길 때까지 프로듀서의 스레드는 무한정 블로킹(Blocking)됩니다. - 위험성: 웹 서버(예: Tomcat)에서 사용자 요청을 처리하던 스레드가 메시지를 보내려다 블로킹되면, 순식간에 웹 서버의 전체 스레드 풀(Thread Pool)이 고갈되어 서비스 전체가 멈추는 연쇄 장애(Cascading Failure)가 발생합니다.
- FAIL (즉각적인 예외 발생):
- 동작: 큐가 가득 찬 상태에서 메시지를 보내면, 브로커는 대기하지 않고 프로듀서에게 즉시
ActiveMQException(Queue is full) 예외를 던집니다. (Classic에서는sendFailIfNoSpace="true"옵션으로 활성화) - 장점: 프로듀서의 스레드가 멈추지 않으므로 웹 서버의 마비를 막을 수 있습니다. 대신 애플리케이션 코드에 이 예외를 잡아서(Catch) 503 에러를 반환하거나 재시도(Retry)하는 백엔드 방어 로직이 반드시 구현되어 있어야 합니다.
5. 아키텍처 설계 시 임계치 산정 모범 사례
- JVM 힙 메모리와의 여유 공간 (Buffer):
memoryUsage를 JVM 전체 힙 메모리의 100%로 설정하는 것은 자살 행위입니다. 브로커 자체를 구동하고 네트워크 연결을 유지하는 데 필요한 기본 메모리가 있기 때문입니다. 항상 힙 메모리의 70% 이하로 설정하여 OOM 발생을 원천 차단해야 합니다. - 디스크 임계치 산정:
storeUsage를 설정할 때, 브로커가 설치된 서버의 실제 물리 디스크 파티션 용량을 반드시 확인해야 합니다. 실제 디스크는 50GB밖에 남지 않았는데 브로커 설정에는 100GB를 허용해 두면, OS 레벨에서 디스크 풀(Disk Full)이 발생하여 데이터베이스가 완전히 깨지는 코럽션(Corruption)이 발생할 수 있습니다. - Fast Failure 원칙 도입:
최신 마이크로서비스 아키텍처(MSA)에서는 시스템이 멈춰서 기다리는 것(BLOCK)보다 빠르게 실패하고 사용자에게 나중에 다시 시도하라고 알리는 것(FAIL)이 훨씬 탄력적입니다. 핵심 비즈니스가 아니라면 과감히 FAIL 정책을 채택하고 서킷 브레이커(Circuit Breaker)와 결합하는 설계를 권장합니다.
'1. 개발 > 1.8. ActiveMQ' 카테고리의 다른 글
| 브로커 간 연결 시 'Duplex' 옵션의 장단점은? (0) | 2026.03.21 |
|---|---|
| 'Strict Order Dispatching' 옵션이 전체 처리량에 미치는 영향은? (0) | 2026.03.20 |
| 'Consumer Window Size'와 네트워크 대역폭의 관계는? (0) | 2026.03.20 |
| 'Producer Window Size'를 통한 클라이언트 흐름 제어 원리는? (0) | 2026.03.20 |
| 브로커 내부 스케줄러가 사용하는 'Job Scheduler' 데이터베이스 구조는? (0) | 2026.03.20 |