Заставить работников мгновенно получать сообщения о сбоях, когда включен режим постоянной доставки
У меня установлен сервер RabbitMQ, где я получаю сообщения, используя Python-Pika. Проблема в том, что если у меня включен постоянный режим доставки, и рабочие не могут обработать сообщение. Вместо выпуска сообщения оно будет сохраняться до тех пор, пока сообщение не будет сброшено до соединения RabbitMQ.
Есть ли способ убедиться, что сообщение, которое не удалось обработать, будет автоматически возвращено в течение разумного периода времени доступным работником, включая того же самого?
Это мой текущий код
if success:
ch.basic_ack(delivery_tag=method.delivery_tag)
else:
syslog.syslog('Error (Callback) -- Failed to process payload: %s' % body)
Идея состоит в том, что я никогда не хочу потерять сообщение, вместо этого я хочу, чтобы оно было переиздано или, скорее, получено снова, если оно не удалось. Это всегда должно иметь место до тех пор, пока сообщение не будет успешно обработано работником. Обычно это происходит, когда один из работников не может открыть соединение с HTTP-сервером.
1 ответ
Я наконец понял, почему это происходит. Я не осознавал, что недостаточно просто подтвердить, что вы закончили с сообщением, но мне также пришлось отклонить любое сообщение, которое вы не смогли обработать, используя channel.basic_reject
, Это может показаться очевидным, но это не поведение по умолчанию для AMQP.
В основном мы должны выпустить сообщение, используя basic_reject
с requeue
установлен в True
, Важным фактором здесь является requeue
ключевое слово, которое предотвращает удаление сообщения и помещает его в очередь, чтобы один из наших доступных сотрудников мог его обработать.
if success:
# On Success - Mark message as processed.
ch.basic_ack(delivery_tag=method.delivery_tag)
else:
# Else - Mark message as rejected and move it back to the queue.
ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)
Я нашел некоторую действительно полезную информацию в этой статье, и есть больше технических деталей о reject
Ключевое слово в этом сообщении в блоге.