2015-09-14 1 views
0

Я подключаюсь к кластеру узлов кролика (A, B) с использованием пружины-amqp. Также предположим, что есть два приемника сообщений (Receiver_1 и Receiver_2), которые использовали соединения с узлом A.Rabbitmq кластер с пружиной не сработает после восстановления после отказа

Когда A опускается, приемники Receiver_1 и Receiver_2 автоматически переключают свои соединения для подключения к B. Предположим, что A появляется, а затем B в кластере отключается. Но приемники не могут потреблять на А снова. Зачем?

Я отладил проект весны, и я обнаружил, что это не ошибка потребителя. На самом деле, весна делает переключение на сервер «A», но следующее исключение возникает:

org.springframework.amqp.rabbit.listener.QueuesNotAvailableException: Не удается подготовить очереди для слушателя. Либо очередь не существует, либо брокер не позволит нам ее использовать. в org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start (BlockingQueueConsumer.java:429) в org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer $ AsyncMessageProcessingConsumer.run (SimpleMessageListenerContainer.java:1022) на Java .lang.Thread.run (Неизвестный источник) Вызвано: org.springframework.amqp.rabbit.listener.BlockingQueueConsumer $ StatementException: Не удалось объявить очереди (ы): [ha.rabbit.channel2] в org.springframework. amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations (BlockingQueueConsumer.java:486) на org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start (BlockingQueueConsumer.java:401) ... 2 м руды

Я проверил файл журнала в rabbidmq:

= ERROR REPORT ==== 14-Sep-2015 :: 03: 45: 41 === Channel ошибку на связи < 0.289 .0> (192.168.1.150:64140 -> 192.168.1.170:5672, vhost: '/', user: 'admin'), канал 2: {amqp_error, not_found, "home node 'rabbit @ vm2' of durable очередь «ha.rabbit.channel2» в vhost '/' недоступна или недоступна », « queue.declare »}

Даже если я перезапущу приложение-потребитель, в то время как в качестве предыдущей конфигурации только сервер A поднят, а B выключен, снова появляется такая же ошибка. Как я могу справиться с этим?

+0

Не знаю о весне, но com.rabbitmq.client имеет https://www.rabbitmq.com/api-guide.html#recovery вариант, который должен решить эту проблему. – Suvitruf

+0

Проверьте это http://stackoverflow.com/a/25189578/1991579 – Suvitruf

ответ

0

Существует open feature request for this.

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

Рамка не знает, когда было бы «хорошим» временем для этого.

Вы можете программно назвать resetConnection() на CachingConnectionFactory, чтобы заставить отказоввозвращения, но, опять же, существующие потребители будут быть затронуты. (resetConnection() было добавлено в 1.5, звоните destroy() в более ранних версиях).

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

Поскольку по умолчанию для всех клиентов используется только одно соединение (в Spring AMQP), существующее сбойное соединение будет использоваться до тех пор, пока оно не сработает.

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

РЕДАКТИРОВАТЬ

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

Затем, в методе createConnection(), вы можете «проверить» первое соединение и использовать его, если оно доступно.

Это приведет к отказу «новых» пользователей (например, RabbitTemplate), но он по-прежнему не решает случай контейнера-слушателя (потребителя); вам придется принудительно выполнить сброс по этому соединению, чтобы заставить их вернуться.