Как диагностировать и решать проблемы с RabbitMQ, такие как задержки и зависания сообщений?
Что проверяют
Умеете ли вы по метрикам отличить три разные беды: консьюмеры не успевают, консьюмер взял сообщения и завис, брокер сам тормозит публикацию. Следом спрашивают про Python-клиент: что происходит с pika при долгой обработке в колбэке.
Как отвечать
Сначала назовите, куда смотрите: Management UI и его HTTP API (по очереди Ready, Unacked, число консьюмеров, скорость publish и ack), CLI (rabbitmqctl list_queues name messages_ready messages_unacknowledged consumers, rabbitmq-diagnostics memory_breakdown), плагин rabbitmq_prometheus с дашбордами Grafana и алертами на рост очередей.
Дальше разбор по симптомам:
- растёт
Ready: консьюмеров мало или они медленные. Добавляете воркеры, профилируете обработчик; - большой
Unacked, который не уменьшается: консьюмер забрал пачку и висит. Ставите разумныйbasic_qos(prefetch_count=...), ищете блокирующий вызов без таймаута. Если ack не приходит дольшеconsumer_timeout(по умолчанию 30 минут), брокер закроет канал и вернёт сообщения в очередь; - публикация встала: сработал memory или disk alarm, и брокер блокирует издателей. Это видно в UI и логах, лечится разбором причины, а не рестартом;
- сообщение крутится по кругу: обработчик падает и делает
nackсrequeue=True. Нужен dead letter exchange, а у quorum-очередей ограничениеdelivery-limit.
Python-специфика: BlockingConnection в pika не потокобезопасен, а длинная обработка в колбэке не даёт отправлять heartbeat. Брокер рвёт соединение, и сообщения доставляются повторно. Решение: обработка в отдельном потоке и ack через connection.add_callback_threadsafe либо асинхронный aio-pika. В Celery то же регулируют worker_prefetch_multiplier и acks_late.
Где спотыкаются
Предлагают перезапустить очередь или брокер. Симптом пропадает, причина остаётся, а неподтверждённые сообщения снова уйдут в обработку.
Ставят TTL, чтобы очередь не росла. Без dead letter exchange это не лечение, а тихая потеря данных.
Считают, что новые узлы в кластере ускорят одну очередь. У очереди один лидер на одном узле, пропускную способность дают несколько очередей, шардирование или стримы.