RabbitMQ - справиться с ненадежным сервисом

У меня есть сервис AAA, который отправляет от 10 до 50 тысяч сообщений в минуту на обмен RabbitMQ. BBB службы.NET Core подписывается на очередь (в которую маршрутизируются все сообщения) и для каждого сообщения вызывает другую HTTP-службу CCC через Интернет. Проблема в том, что CCC очень ненадежен, несколько раз в день он полностью отключается на минуту или две, и, по крайней мере, один раз в неделю он умирает на час.

У меня нет контроля над AAA или CCC. Как я могу использовать функции маршрутизации RabbitMQ для надежной доставки всех проблемных сообщений?

2 ответа

Для ненадежной сторонней службы CCC, которая отключается на несколько минут или часов, может быть полезен автоматический выключатель. Настройте автоматический выключатель на размыкание, когда он обнаружит, что CCC находится в автономном режиме.

Вы можете отслеживать состояние автоматического выключателя, чтобы определять, когда CCC находится в автономном режиме, и / или регистрировать изменения состояния цепи для последующего анализа.

Автоматический выключатель Полли позволяет подключать любой пользовательский код к переходам состояния цепи, поэтому вы также можете:

  • когда цепь обрывается, отписаться от очереди RabbitMQ.
  • когда цепь наполовину размыкается, повторно подпишитесь на очередь RabbitMQ с узким параллелизмом (скажем, с счетчиком предварительной выборки только 1 или 2 ... только сообщений, достаточных для автоматического выключателя, чтобы повторить попытку цепи).
  • когда канал закрывается (снова исправно), повторно подпишитесь на очередь RabbitMQ с полной пропускной способностью.

Этот шаблон будет препятствовать тому, чтобы вы получали 100000 сообщений, передаваемых в ошибку / недоставленное письмо / вашу очередь повторных попыток RabbitMQ, как только автоматический выключатель обнаружит, что CCC находится в автономном режиме.

Вам по-прежнему необходимо учитывать, что происходит с сообщениями, которые действительно не работают (до обрыва цепи или при повторном тестировании), как описано в другом ответе. Направьте их в очередь ошибок / повторов. Или, если шаблон unsubscribe-when-CCC-is-down работает достаточно хорошо с вашими реальными параметрами, вы можете позволить сообщениям, которые потерпели неудачу, просто вернуться в исходную очередь.


Если CCC также испытывает какие-либо временные сбои (сбои только в течение нескольких секунд), рассмотрите возможность введения политики WaitAndRetry.


Поскольку скорость входящих сообщений потенциально составляет 1000 с в секунду, вы, вероятно, захотите подумать о том, как вы ограничиваете параллельность обработки сообщений в BBB и / или время ожидания, установленное для вызовов в CCC. Без этого вы можете рискнуть выпуклостями памяти у потребителя, так как поступает все больше и больше сообщений, в то время как другие запросы висят в ответе от CCC до истечения времени ожидания; большой тайм-аут на CCC явно усугубляет это. Потребительский параллелизм может быть ограничен с помощью ручного ack и применяя pre-fetch count,

Предполагая, что ваш метод подписки в AAA является синхронным, создание исключения приведет к тому, что Rabbit поместит сообщение в очередь недоставленных сообщений. Оттуда вы можете переместить их назад или вручную осмотреть их. В качестве альтернативы, вы можете повторно опубликовать его в том же обмене, но у вас могут возникнуть проблемы с сообщениями, которые снова и снова сбиваются при заполнении очереди. Чтобы избежать этого, опубликуйте его с заголовком, который не позволит ему снова войти в исходную очередь. Создайте другую постоянную очередь, которая использует ваш новый заголовок в качестве фильтра. Presto, у вас есть очередь для повторной попытки. Вы можете подписаться на него для повторных попыток и / или предупреждений, использовать Shovel для перемещения сообщений обратно в исходную очередь, что угодно.

Другие вопросы по тегам