Мы успешно используем Кролика около года. Недавно обновили до версии 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, и поэтому готов поверить, что здесь есть тонкость в потреблении от кластерного брокера, которую я еще не грокнул!
Спасибо, -- Стив