2014-11-24 3 views
7

Может ли кто-нибудь объяснить, что происходит за кулисами в кластере RabbitMQ с несколькими узлами и очередями зеркальным способом при публикации на подчиненный узел?Поведение кластеров и зеркальных очередей RabbitMQ за кадром

Из того, что я читал, кажется, что все действия, кроме опубликования, идут только к ведущему, а ведущий затем передает действие действий подчиненным (это из документации). Формулируйте мое понимание, это означает, что потребитель всегда будет потреблять сообщение из главной очереди. Кроме того, если я отправлю запрос подчиненному устройству для потребления сообщения, этот ведомый будет выполнять дополнительный прыжок, перейдя к мастеру для получения этого сообщения.

Но что происходит, когда я публикую на подчиненном узле? Будет ли этот узел делать то же самое, что и сначала отправить сообщение хозяину?

Кажется, что есть много лишних прыжков при работе с рабами, поэтому, похоже, вы могли бы улучшить производительность, если знаете только мастера. Но как вы справляетесь с мастер-неудачей? Тогда один из рабов будет избран мастером, поэтому вы должны знать, к чему подключиться?

Прошу об этом, потому что мы используем кластер RabbitMQ с HAProxy спереди, поэтому мы можем отделить структуру кластера от наших приложений. Таким образом, всякий раз, когда узел завершается, HAProxy перенаправляется на живые узлы. Но у нас есть проблемы, когда мы убиваем один из узлов кролика. Соединение с кроликом является постоянным, поэтому, если это не удается, вы должны его воссоздать. Кроме того, вы должны повторно отправить сообщения в этом случае, иначе вы потеряете их.

Даже со всем этим сообщения все еще могут быть потеряны, поскольку они могут быть в пути, когда я убиваю узел (в некоторых буферах, где-то в сети и т. Д.). Таким образом, вам необходимо использовать транзакции или подтверждения издателя, которые гарантируют доставку после того, как все зеркала были заполнены сообщением. Но вот еще одна проблема. Возможно, у вас есть повторяющиеся сообщения, потому что брокер мог отправить подтверждение, которое никогда не достигало производителя (из-за сбоев сети и т. Д.). Поэтому потребительские приложения должны будут выполнять дедупликацию или обрабатывать входящие сообщения в идемпотентном порядке.

Есть ли способ избежать этого? Или я должен решить, могу ли я потерять пару сообщений против дублирования некоторых сообщений?

ответ

14

Может кто-нибудь объяснить, что происходит за кулисами в кластере RabbitMQ с несколькими узлами и очередями в зеркальном режиме при публикации на подчиненный узел?

This блог описывает, что именно происходит.

Но что происходит, когда я публикую на подчиненном узле? Будет ли этот узел делать то же самое, что и сначала отправить сообщение хозяину?

Сообщение будет перенаправлено на главную очередь - то есть узел, на котором была создана очередь.

Но как вы справляетесь с главной неудачей? Тогда один из рабов будет избран мастером, поэтому вы должны знать, к чему подключиться?

Опять же, это покрыто here. По сути, вам нужна отдельная служба, которая опросит RabbitMQ и определяет, ожидают ли узлы или нет. Для этого RabbitMQ предоставляет management API.Ваши публикации и потребляющие приложения должны ссылаться на эту услугу либо напрямую, либо через хранилище взаимных данных, чтобы определить, какой правильный узел должен публиковать или потреблять.

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

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

Даже при всем этом, сообщения по-прежнему могут быть потеряны, потому что они могут находиться в пути, когда я убиваю узел

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

Поэтому потребительские приложения должны будут выполнять дедупликацию или обрабатывать входящие сообщения идемпотентным образом.

Вы можете справиться с этим несколькими способами. Например, установка message-ttl на относительно низкое значение гарантирует, что дублированные сообщения не будут оставаться в очереди в течение длительных периодов времени. Вы также можете пометить каждое сообщение уникальной ссылкой и проверить эту ссылку на уровне потребителя. Конечно, для этого потребуется хранить кеш обработанных сообщений для сравнения входящих сообщений; идея состоит в том, что если поступило ранее обработанное сообщение, его тег будет кэширован потребителем, и сообщение можно будет проигнорировать.

Одна вещь, которую я хотел бы подчеркнуть с помощью AMQP и решений на основе очереди, заключается в том, что ваша инфраструктура предоставляет инструменты, но не все решение. Вы должны устранить эти пробелы в зависимости от потребностей вашего бизнеса. Часто наилучшее решение получается путем проб и ошибок. Надеюсь, мои предложения полезны. Здесь я расскажу о нескольких проектных решениях RabbitMQ, в том числе о тех проблемах, которые вы упомянули, here, если вам интересно.

+1

Спасибо, Пол. Вы бог. Чтобы убедиться, прежде чем я перейду к реализации, вы можете подтвердить это: 1) Я могу использовать все еще использование HAProxy, и издатель подтверждает, и я не потеряю никакого сообщения. У меня будут повторяющиеся сообщения, которые мне нужно как-то удалить. У меня будут проблемы с производительностью (из-за дополнительных переходов к мастеру при первом доступе к ведомым устройствам), но мои данные будут «пуленепробиваемыми». 2) Чтобы повысить производительность, я создам службу мониторинга, поэтому каждый раз я буду отправлять запросы только мастеру, но мне все равно нужно иметь дело с дубликатами. Благодарю. –

+1

Вы все еще можете использовать HAProxy, но вы будете нести дополнительные сетевые перелеты с круговой конфигурацией. Если вы хотите добиться равномерной балансировки нагрузки, прочитайте это: http://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/ Очень маловероятно, что у вас будут повторяющиеся сообщения.Я думаю, что установить свойство message-ttl достаточно, чтобы удалить дубликаты, хотя добавление ссылочного тега, как я упоминал, решит проблему. Я выпущу библиотеку RabbitMQ на C#, которая вскоре выберет все вышеперечисленное. Следите за моим блогом за обновлениями. –

+1

На самом деле у меня были дублирующие сообщения. Я проверил пару раз, публикуя 10000 сообщений для кластера с двумя узлами. Я убил один узел, и я получил 10011-10012 сообщений. Один из моих потребляющих API - идемпотент, так что конечный результат был в порядке. Большое спасибо. –

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