Вопрос проверяет знание практических рычагов RabbitMQ: как контролировать количество сообщений “в полете”, подтверждения, повторную доставку и маршрутизацию ошибок.
Подтверждение управляется выбором режима: авто-ack или ручной ack (basic_ack). Повторная доставка зависит от basic_nack/basic_reject и флага requeue, а также от падения канала (все unacked вернутся в очередь). Количество одновременно выданных сообщений регулируется basic_qos(prefetch_count=...). Для “плохих” сообщений используют DLX/DLQ, чтобы они уходили в отдельную очередь вместо бесконечных повторов. Для ретраев применяют TTL и dead-letter маршрутизацию или отложенную доставку через отдельные механизмы.
Управление подтверждением и повторной доставкой делится на настройки потребителя и параметры очереди/политики.
Режим подтверждения
auto-ack: сообщение считается обработанным сразу при доставке (риск потерь при падении воркера)
manual ack: явный basic_ack после обработки
nack/reject и requeue
basic_nack(..., requeue=True) вернет сообщение в очередь для повторной обработки
requeue=False обычно отправит сообщение в DLQ (если настроен DLX), иначе сообщение может быть отброшено (зависит от конфигурации)
QoS / Prefetch
basic_qos(prefetch_count=N) ограничивает число unacked на канале/потребителе
channel.basic_qos(prefetch_count=50)
channel.basic_consume(queue="tasks", on_message_callback=on_message, auto_ack=False)
Здесь важна логика: очередь сама по себе не “включает ack”, но задает правила, куда идут сообщения при отказах и как долго живут.
Dead Letter Exchange (DLX)
аргументы очереди: x-dead-letter-exchange, x-dead-letter-routing-key
используются, чтобы “отбитые”/просроченные сообщения уходили в DLQ
TTL
x-message-ttl (время жизни сообщений в очереди)
x-expires (время жизни самой очереди)
вместе с DLX TTL часто используется для retry-очередей: сообщение “ждет” TTL, затем улетает обратно в основную очередь через DLX
Ограничение длины очереди
x-max-length, x-max-length-bytes
при переполнении сообщения могут “выталкиваться” (обычно в DLX при правильной настройке), что влияет на гарантию “не потерять”
Retry через отдельные очереди
main -> retry(с TTL) -> main
после N попыток отправлять в DLQ для ручного разбора
Счетчик попыток
хранить счетчик в заголовках/метаданных или во внешнем хранилище
после превышения лимита: requeue=False и маршрутизация в DLQ
Вывод
На практике управление подтверждением и повторной доставкой строят вокруг manual ack, nack/requeue, prefetch, а для “плохих” сообщений добавляют DLX/DLQ и retry-схемы через TTL или отдельные очереди.