2014-01-07 4 views
2

У нас есть проблема в нашей установке Rebus/RabbitMQ, где Rebus внезапно прекращает получать/обрабатывать сообщения от RabbitMQ. Это произошло два раза за последний месяц, и мы не уверены, как это сделать.Ребус останавливает получение сообщений от RabbitMQ

У нашей установки RabbitMQ есть два узла на разных серверах, а сторона Rebus - это служба Windows.

Мы не видим ошибок в Rebus или в журнале событий на сервере, на котором работает Rebus. Мы также не видим ошибок на серверах RabbitMQ.

Rebus (и служба Windows) продолжает работать, поскольку мы видим другие сообщения журнала, такие как DueTimeOutSchedular и timeoutreplies. Однако кажется, что рабочий поток перестает работать, но без ошибок регистрируется.

Это приводит к входной очереди RabbitMQ, что продолжает расти :(, мы добавим протоколирования для мониторинга это так, мы получаем уведомление, если это случится снова.

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

UPDATE кажется, что мы на самом деле есть сбои узла, по крайней мере, в последний раз это случилось. Мастер RabbitMQ узел разбился (сервер разбился), а подчиненный был повышен до уровня ведущего. Насколько я могу видеть из журналов RabbitMQ на узлах все вэнь t согласно планируемому. Других ошибок в журналах RabbitMQ нет.

В то время, когда это произошло, Rebus был настроен на подключение только к узлу, который был подчиненным (затем продвигался на ведущий), так что у Rebus не возникало сбой rabbitmq и, следовательно, ошибки соединения с Rebus. Однако, похоже, что Rebus прекратил обработку сообщений, когда произошел сбой.

Мы действительно испытываем это на нескольких очередях, которые, кажется, и некоторые из них, но не все, похоже, оказались в несинхронизированном состоянии.

UPDATE 2 Я смог воспроизвести проблему довольно легко, так что это может быть проблема конфигурации в нашей настройке. Но это то, что мы делаем, чтобы воспроизвести его.

  1. Начать два узла в кластере, например. rabbit1 (мастер) и rabbit2 (раб)
  2. Ребус подключается к rabbit2, ведомое
  3. Закрыть rabbit1, мастер. rabbit2 способствует освоить

Очереди зеркальные

У нас есть два небольших тестов приложения для воспроизведения этого, «отправитель», который посылает сообщение каждую секунду и «потребителей», который обрабатывает сообщения ,

Когда rabbit1 закрыт, «потребитель» прекращает обработку сообщений, но «отправитель» продолжает отправлять сообщения, и очередь продолжает расти.

  1. Start rabbit1 снова, он присоединяется в качестве ведомого устройства

Это не имеет никакого эффекта, и «потребитель» до сих пор не обрабатывает сообщения.

  1. Перезагрузка «потребитель» приложение

Когда «потребитель» перезапуск он извлекает все сообщения и обрабатывает их.

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

Ребус все еще подключен к RabbitMQ, мы видим, что во вкладке соединений на сайте управления, то «потребители» отправить/ПОЛУЧАЛ B/S падение до 2 B/s, когда он прекращает обработку сообщений

UPDATE 3 Итак, я загрузил источник Rebus и присоединился к нашему процессу, чтобы я мог видеть, что происходит в классе «RabbitMqMessageQueue», когда он останавливается. Когда «rabbit1 * замкнута на "BasicDeliverEventArgs" имеет нулевое значение, это код

BasicDeliverEventArgs ea; 
if (!threadBoundSubscription.Next((int)BackoffTime.TotalMilliseconds, out ea)) 
{ 
    return null; 
} 

// wtf?? 
if (ea == null) 
{ 
    return null; 
} 

См: https://github.com/rebus-org/Rebus/blob/master/src/Rebus.RabbitMQ/RabbitMqMessageQueue.cs#L178

Мне нравится "WTF ??" комментарий :)

ответ

3

Это звучит очень странно !

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

Вы можете увидеть соответствующее место в источнике здесь: https://github.com/rebus-org/Rebus/blob/master/src/Rebus.RabbitMQ/RabbitMqMessageQueue.cs#L205

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

Когда вы столкнулись с этой ошибкой, вы проверили вкладку «соединения» в пользовательском интерфейсе управления RabbitMQ и посмотрели, был ли клиент еще подключен?

Обновление:

Спасибо за вас тщательное расследование :)

"WTF ??" находится там, потому что я когда-то испытывал икоту, когда ea, по-видимому, был нулевым, что было неожиданным в то время, что привело к появлению NullReferenceException и рвоту исключений по всем моим журналам.

По the docs, Next возвращает истину и установить result в нуль, когда он достигает «конец-потока», который, по-видимому, что происходит, когда базовая модель закрыта.

Правильное поведение в этом случае для Rebus должно было бы сделать правильное исключение и позволить восстановить соединение - я это сразу же реализую!

Сядьте крепко, у меня будет готовое решение в течение нескольких минут!

+0

спасибо. Я запускаю свои тестовые приложения несколько раз и не могу воспроизвести ошибку, она правильно обнаруживает конец потока и повторно подключается. Однако мы видим «Произошла ошибка при откате транзакции!» ошибка, но это также происходит при «нормальной» ошибке соединения. Rebus теперь продолжает получать сообщения :) –

+0

Спасибо, что помогли мне улучшить Rebus - это было очень полезное описание ошибки! :) – mookid8000

Смежные вопросы