RabbitMQ 문제 해결: 명령어로 큐 및 메시지 문제 진단하기
신속한 RabbitMQ 문제 해결을 위한 `rabbitmqctl` 명령줄 유틸리티 마스터하기. 이 가이드는 과도한 큐 백로그, 멈춘 메시지, 소비자 연결 부재, 잘못된 교환 바인딩 등 일반적인 문제를 진단하는 실용적이고 실행 가능한 명령어를 제공합니다. UI에만 의존하지 않고 메시지 흐름을 신속히 복원하는 필수 진단법을 배워보세요.
RabbitMQ 문제 해결: 명령어로 큐 및 메시지 문제 진단하기
RabbitMQ 큐가 멈춘 것처럼 보일 때, 가장 나쁜 첫 번째 조치는 보통 큐를 비우는 것입니다. 두 번째로 나쁜 조치는 브로커를 재시작하고 문제가 해결되길 바라는 것입니다. 대부분의 큐 문제는 흔적을 남깁니다: 준비된 메시지, 확인되지 않은 메시지, 누락된 소비자, 차단된 발행자, 라우팅 불가능한 메시지, 조용히 채워지는 데드레터 큐, 또는 연결되어 있지만 아무것도 확인하지 않는 소비자.
이 가이드는 RabbitMQ 명령어를 사용하여 터미널에서 문제를 좁혀 나갑니다. 브로커 측 상태를 확인하기 위해 rabbitmqctl을 주로 사용하고, 메시지를 안전하게 샘플링하는 등 관리 API 작업이 필요할 때는 rabbitmqadmin을 사용합니다. 예제는 -p <vhost> 옵션이 표시되지 않는 한 기본 가상 호스트를 가정합니다. 실제 시스템에서는 항상 vhost를 포함하세요; 많은 잘못된 진단은 누군가가 /를 확인하는 동안 애플리케이션이 payments나 prod를 사용하기 때문에 발생합니다.
rabbitmqctl 이해하기
rabbitmqctl 명령어는 RabbitMQ 관리 계층과 상호작용하기 위한 명령줄 인터페이스(CLI) 역할을 합니다. 이를 통해 사용자, 권한, 교환, 큐, 바인딩을 관리할 수 있으며, 문제 해결에 가장 중요한 것은 브로커의 런타임 통계를 검사할 수 있다는 점입니다.
실행 참고 사항: 대부분의 명령어는 루트 권한이 필요하거나 명령어를 실행하는 사용자가 rabbitmq 그룹의 구성원이어야 하며, sudo를 사용해야 할 수도 있습니다.
큐 백로그 및 멈춘 메시지 진단하기
가장 흔한 문제 중 하나는 큐가 계속 커지는 것으로, 메시지가 소비되는 속도보다 생산되는 속도가 빠르거나 소비자가 처리를 중단했음을 나타냅니다.
큐부터 시작하되, 올바른 열을 요청하세요
기본 list_queues 출력은 문제 해결에 너무 부족합니다. "전달 대기 중"과 "전달되었지만 확인되지 않음"을 구분하는 열을 요청하세요.
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged messages consumers state
이렇게 해석하세요:
| 증상 | 의미 |
|---|---|
messages_ready 증가, consumers가 0 |
큐에 구독 중인 활성 소비자가 없습니다. 배포, 자격 증명, vhost, 큐 이름을 확인하세요. |
messages_ready 증가, 소비자 존재 |
소비자가 너무 느리거나, 차단되었거나, 워크로드에 비해 프리페치가 너무 낮습니다. |
messages_unacknowledged 높고 안정적 |
소비자가 메시지를 받았지만 확인(ack)하지 않고 있습니다. 멈춘 핸들러나 너무 높은 프리페치 값을 확인하세요. |
state가 running이 아님 |
큐를 사용할 수 없거나, 동기화 중이거나, 노드 문제의 영향을 받고 있을 수 있습니다. 클러스터 및 큐 리더 상태를 확인하세요. |
쿼럼 큐의 경우 리더 및 멤버십 열을 추가하세요:
rabbitmqctl -p / list_queues name type leader members online messages_ready messages_unacknowledged consumers state
이것이 중요한 이유는 큐가 한 노드에 정상적인 소비자를 가지고 있지만 리더가 다른 곳에 있거나, 쿼럼 큐가 충분한 멤버가 온라인 상태가 되기를 기다리고 있을 수 있기 때문입니다.
목록이 길면 표준 셸 도구로 필터링하세요:
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged consumers state \
| awk '$2 > 0 || $3 > 0 || $4 == 0'
브로커가 발행자를 차단하고 있는지 확인하세요
rabbitmqctl status
rabbitmq-diagnostics alarms
메모리 및 디스크 알람이 큐가 잘못 구성되었다는 의미는 아니지만, "아무것도 움직이지 않는" 많은 사고를 설명합니다. RabbitMQ가 메모리 또는 디스크 여유 공간 알람을 발생시키면 발행 연결을 차단할 수 있습니다. 소비자는 여전히 메시지를 소비할 수 있으므로, 가시적인 증상은 불균형할 수 있습니다: 일부 큐는 줄어들고, 다른 큐는 새 작업 수신을 중단하며, 발행자는 타임아웃됩니다.
또한 리스너와 노드 상태를 확인하세요:
rabbitmq-diagnostics ping
rabbitmq-diagnostics listeners
rabbitmq-diagnostics check_running
rabbitmq-diagnostics check_local_alarms
추측하지 말고 소비자 검사하기
list_connections는 누가 연결되어 있는지 알려줍니다. list_channels는 해당 연결이 채널을 열었는지, 그리고 얼마나 많은 작업을 보유하고 있는지 알려줍니다.
rabbitmqctl list_connections name user peer_host peer_port state channels recv_oct send_oct
rabbitmqctl list_channels connection name number consumer_count messages_unacknowledged prefetch_count state
유용한 패턴은 간단합니다:
- 예상 호스트에서 연결이 없음: 애플리케이션이 다운되었거나, 브로커를 해석할 수 없거나, 인증할 수 없거나, 다른 환경에 연결 중입니다.
- 연결은 있지만 채널이 없음: 클라이언트가 연결되었지만 선언하거나 소비하기 전에 실패했습니다.
- 채널은 있지만
consumer_count가0: 앱이 게시만 하거나, 소비자 구독이 실패했을 수 있습니다. - 한 채널에서
messages_unacknowledged가 높음: 해당 소비자가 메모리에 작업을 보유하고 있으며 빠르게 ack을 반환하지 않고 있습니다.
명명된 연결을 사용하는 경우 클라이언트 구성에 connection_name을 포함하세요. 10.42.8.17:52344 -> 10.42.1.20:5672 같은 줄은 billing-worker-7보다 덜 유용합니다.
소비자를 탓하기 전에 바인딩 확인하기
큐가 비어 있지만 애플리케이션이 메시지를 발행했다고 말할 때, 다음으로 확인할 곳은 라우팅입니다.
rabbitmqctl -p / list_exchanges name type durable auto_delete internal arguments
rabbitmqctl -p / list_bindings source_name source_kind destination_name destination_kind routing_key arguments
직접 교환(direct exchange)은 정확한 라우팅 키 일치가 필요합니다. 토픽 교환(topic exchange)은 한 단어에 *, 0개 이상의 단어에 #을 사용합니다. 팬아웃 교환(fanout exchange)은 라우팅 키를 무시합니다. 교환에 일치하는 바인딩이 없고 대체 교환(alternate exchange)도 없으면 메시지는 라우팅 불가능합니다. 어딘가에 비밀리에 대기하고 있지 않습니다.
발행자 측 확인을 위해 필수 발행( mandatory publishing)을 사용하고 클라이언트에서 반환된 메시지를 처리하세요. 브로커 측에서는 관리 UI와 메트릭이 일반적으로 rabbitmqctl보다 속도 측면에서 더 좋지만, list_bindings는 일반적인 실수(잘못된 vhost, 잘못된 교환, 철자가 틀린 라우팅 키, 배포 후 이전 교환에 바인딩된 큐)를 잡기에 충분합니다.
메시지를 안전하게 샘플링하기
최신 RabbitMQ에는 일반적인 rabbitmqctl queue_get 명령어가 없습니다. rabbitmqadmin 또는 HTTP API를 통해 관리 플러그인을 사용하세요. 주의해서 수행하세요: ack 모드에 따라 메시지를 가져오면 메시지를 제거하거나 다시 큐에 넣을 수 있습니다.
rabbitmqadmin -V / get queue=orders.pending count=3 ackmode=ack_requeue_true
이것을 사용하여 좁은 질문에 답하세요: 페이로드가 유효한 JSON인가, 메시지 유형이 소비자가 예상하는 것과 일치하는가, 필수 헤더가 누락되었는가, 라우팅 키가 프로듀서 팀이 말한 것과 같은가? 바쁜 프로덕션 큐에서 대량 검사 도구로 사용하지 마세요.
데드레터 이동 확인하기
지연된 처리는 종종 데드레터 큐가 조용히 커지는 것으로 나타납니다.
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged arguments policy
rabbitmqctl -p / list_bindings source_name destination_name routing_key arguments \
| grep -E 'dead|dlx|retry|parking'
x-dead-letter-exchange, x-dead-letter-routing-key, x-message-ttl, x-max-length, x-overflow와 같은 큐 인수는 메시지가 만료되거나, 거부되거나, 길이 제한에 도달할 때 이동하는 위치를 변경합니다. 애플리케이션이 지연 큐를 통해 데드레터링하여 재시도하는 경우, 잘못된 바인딩이 루프를 생성할 수 있습니다. 증상은 "지연된 메시지"처럼 보이지만, 실제 문제는 메시지가 최종 처리 큐나 파킹 로트 큐에 도달하지 못하고 큐 사이를 순환하는 것입니다.
실용적인 명령어 시퀀스
누군가 "주문이 멈췄다"고 보고하면, 보통 이 시퀀스를 실행합니다:
rabbitmq-diagnostics ping
rabbitmq-diagnostics check_local_alarms
rabbitmqctl -p orders list_queues name type messages_ready messages_unacknowledged consumers state
rabbitmqctl list_connections name user peer_host state channels
rabbitmqctl list_channels connection consumer_count messages_unacknowledged prefetch_count state
rabbitmqctl -p orders list_bindings source_name destination_name routing_key arguments
messages_ready가 높고 consumers가 0이면 소비자 배포를 확인하세요. messages_unacknowledged가 높으면 소비자 로그와 프리페치 설정을 확인하세요. 큐가 비어 있지만 발행자가 성공을 보고하면 바인딩과 발행자 확인을 검사하세요. 알람이 활성화되어 있으면 애플리케이션 로직을 추적하기 전에 브로커 리소스 압박을 해결하세요. 이렇게 하면 조사가 브로커가 실제로 수행하는 작업에 기반을 두게 됩니다.