Как я могу восстановить непризнанные сообщения AMQP с других каналов, кроме собственного соединения?

кажется, чем дольше я держу свой сервер rabbitmq, тем больше у меня проблем с неподтвержденными сообщениями. Я бы с удовольствием запросил их. На самом деле для этого существует команда amqp, но она применяется только к каналу, который использует ваше соединение. Я построил небольшой скрипт pika, чтобы хотя бы попробовать его, но я либо чего-то не хватает, либо это нельзя сделать таким образом (как насчет rabbitmqctl?)

import pika

credentials = pika.PlainCredentials('***', '***')
parameters = pika.ConnectionParameters(host='localhost',port=5672,
    credentials=credentials, virtual_host='***')

def handle_delivery(body):
    """Called when we receive a message from RabbitMQ"""
    print body

def on_connected(connection):
    """Called when we are fully connected to RabbitMQ"""
    connection.channel(on_channel_open)    

def on_channel_open(new_channel):
    """Called when our channel has opened"""
    global channel
    channel = new_channel
    channel.basic_recover(callback=handle_delivery,requeue=True)    

try:
    connection = pika.SelectConnection(parameters=parameters,
        on_open_callback=on_connected)    

    # Loop so we can communicate with RabbitMQ
    connection.ioloop.start()
except KeyboardInterrupt:
    # Gracefully close the connection
    connection.close()
    # Loop until we're fully closed, will stop on its own
    connection.ioloop.start()

3 ответов


неподтвержденные сообщения-это те, которые были доставлены по сети потребителю, но еще не были ack'ed или отклонены , но этот потребитель еще не закрыл канал или соединение, по которому он первоначально получил их. Поэтому брокер не может понять, просто ли потребитель долго обрабатывает эти сообщения или забыл о них. Таким образом, он оставляет их в непризнанном состоянии до тех пор, пока потребитель не умрет или они не получат ack'ed или отвергнутый.

поскольку эти сообщения все еще могут быть достоверно обработаны в будущем все еще живым потребителем, который первоначально их потреблял, вы не можете (насколько мне известно) вставить другого потребителя в микс и попытаться принять внешние решения о них. Вы должны исправить своих потребителей, чтобы принимать решения о каждом сообщении по мере их обработки, а не оставлять старые сообщения непризнанными.


Если сообщения unacked есть только два способа, чтобы получить их обратно в очередь:

  1. basic.НАК!--6-->

    эта команда вызовет сообщение помещается обратно в очередь и повторно.

  2. отключиться от брокера

    эта акция заставит всех unacked сообщения из этого канала, чтобы быть положить обратно в очередь.

Примечание: basic.recover попытается переиздать распакованные сообщения на том же канале (тому же потребителю), что иногда является желаемым поведением.

спецификация RabbitMQ для basic.восстановить и основные.НАК!--26-->


реальный вопрос: почему сообщения не подтверждены?

возможные сценарии, чтобы вызвать unacked сообщения:

  1. потребитель получение слишком много сообщений, а затем не обработка и acking их достаточно быстро.

    решение: предварительная выборка как можно меньше сообщений.

  2. багги клиентская библиотека (у меня есть эта проблема в настоящее время с пищуха 0.9.13. Если в очереди много сообщений, определенное количество сообщений застрянет распакованным, даже через несколько часов.

    решение: мне приходится перезагружать несколько раз, потребительскими, пока все unacked сообщения не ушли от очередь.


все неподтвержденные сообщения перейдут в состояние готовности, как только все рабочие/потребители будут остановлены.

обеспечьте что все работники остановлены путем подтверждать с grep on ps aux вывод и остановка / убийство их, если они найдены.

Если вы управляете работниками с помощью супервизора, который показывает, как рабочий остановлен, вы можете проверить наличие зомби. Супервизор сообщает, что работник будет остановлен, но все же вы найдете процессы зомби, работающие при grepped на ps aux выход. Убийство процессов зомби вернет сообщения в состояние готовности.