Неизвестный тег доставки из RabbitMQ при подтверждении сообщения в кластере с реплицированными очередями

Мы успешно используем Кролика около года. Недавно обновили до версии 2.6.1, так как хотим использовать кластеры с реплицированными очередями сообщений.

Мое тестирование выявило загадочное поведение, которое для меня пахнет кроличьей ошибкой. Тест, раскрывающий это, работает с кластером из двух узлов. Оба узла работают под управлением версии 2.6.1. Оба узла имеют диск. Оба узла работают на Mac OS, хотя я сомневаюсь, что это уместно.

Я также запускаю Алису на узле, который запускает тест. Тест использует его для программного выполнения stop_app на одном из узлов, потому что тест пытается проверить, что, если мастер кластера выходит из строя, а подчиненный поднимается, чтобы занять его место, мы не теряем сообщения.

Итак, тест имеет небольшой пул потоков, которому даются задачи, которые периодически 1) публикуют сообщения и 2) переключают состояние главного узла Rabbit (остановлен, если работает; запущен, если остановлен). Другие потоки потребляют сообщения из очередей.

Я использую подтверждения издателя, а также подтверждаю сообщения от потребителей (используя autoAck=false для channel.basicConsume()).

Когда главный узел останавливается, я вижу, что и производители, и потребители перехватывают ShutdownSignalException. Они справляются с этим, пытаясь повторно подключиться к кластеру. Это прекрасно работает. При повторном подключении они продолжают заниматься своими делами.

Иногда я вижу, что потребитель успешно получил сообщение от брокера и вызывает channel.basicAck(), когда получает исключение ShutdownSignalException.

Позже, когда потребитель повторно подключится, он снова выведет то же сообщение. (Тело сообщения помечено UUID, поэтому я знаю, что это одно и то же.) На этот раз, когда потребитель пытается выполнить basicAck() сообщение, он снова получает ShutdownSignalException, но в нем есть следующий текст: " answer-text=PRECONDITION_FAILED - неизвестный тег доставки 7".

Фактически, это тот же тег доставки, который был предложен потребителю брокером до того, как мастер вышел из строя и потребитель снова подключился.

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

Но как это может быть так? Если первое подтверждение прошло успешно, то сообщение должно быть удалено из очередей брокера, и потребитель больше не должен видеть это сообщение.

Тем не менее, если первое подтверждение не удалось, то потребитель не должен быть наказан за попытку повторного подтверждения сообщения.

Кто-нибудь видел это раньше? Для меня это пахнет ошибкой в ​​​​реплицированных очередях Rabbit, но я все еще новичок в Rabbit, и поэтому готов поверить, что здесь есть тонкость в потреблении от кластерного брокера, которую я еще не грокнул!

Спасибо, -- Стив


person Steve Rehrauer    schedule 30.09.2011    source источник
comment
Вы когда-нибудь понимали это, потому что у меня очень похожая проблема.   -  person Jeff Hutchins    schedule 28.12.2012


Ответы (1)


Я не уверен, соответствует ли мой случай вашему, но я видел похожий «неизвестный тег доставки» при попытках подтверждения после повторного подключения, а затем снова появлялось то же сообщение. Сначала это выглядело как ошибка, но на самом деле это ожидаемое поведение. Потребитель с QOS>1 может иметь в своем локальном буфере некоторые сообщения, и тег доставки будет недействительным для всех них после повторного подключения. С другой стороны, попытка подтвердить даже текущее сообщение после повторного подключения не имеет никакого смысла, потому что это сообщение уже было автоматически удалено при потере соединения, и поэтому я получил его снова.

person Umputun    schedule 29.06.2013