Публикация / подписка для надежного обмена сообщениями: Redis VS RabbitMQ

Фон

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

Издатель и потребитель находятся на разных машинах, и связь между ними может иногда прерываться.

Задача

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

Заказ сообщений не является обязательным.

Проблема

Согласно моим исследованиям, RabbitMQ - правильный выбор для этого сценария:

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

С другой стороны, Redis тоже может это делать:

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

Вопросов

  1. Какое решение было бы проще всего реализовать для этого варианта использования? (Решение Redis или решение RabbitMQ?)
  2. Пожалуйста, дайте ссылку на пример того, что, по вашему мнению, было бы лучше всего!

person Flame_Phoenix    schedule 04.05.2017    source источник


Ответы (3)


Фон

Изначально я хотел опубликовать и подписаться с сохранением сообщений и очереди.

Теоретически это не совсем подходит для публикации и подписки:

  • этому шаблону безразлично, получены сообщения или нет. Издатель просто рассылает сообщения веером, и если есть подписчики, которые слушают, хорошо, в противном случае ему все равно.

На самом деле, глядя на мои потребности, мне понадобится больше шаблона Work Queue или даже RPC.

Анализ

Люди говорят, что и то, и другое должно быть простым, но на самом деле это субъективно.

RabbitMQ имеет лучшую официальную документацию в целом с четкими примерами на большинстве языков, в то время как информация Redis в основном находится в сторонних блогах и в редких репозиториях на github, что значительно затрудняет ее поиск.

Что касается примеров, у RabbitMQ есть два примера, которые четко отвечают на мои вопросы:

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

Падение rabbitMQ:

  • Самая большая проблема этого подхода заключается в том, что в случае сбоя потребителя / работника вам необходимо самостоятельно определить логику, чтобы гарантировать, что задачи не будут потеряны. Это происходит потому, что после завершения задачи, следуя шаблону RPC с устойчивыми очередями из рабочих очередей, сервер будет продолжать отправлять сообщения работнику до тех пор, пока он снова не вернется в рабочее состояние. Но рабочий не знает, прочитал ли он уже ответ от сервера или нет, поэтому ему потребуется несколько ACK от сервера. Чтобы исправить это, каждое рабочее сообщение должно иметь идентификатор, который вы сохраняете на диск (в случае сбоя), или запросы должны быть идемпотентными.
  • Другая проблема заключается в том, что если соединение потеряно, клиенты взорвутся с ошибками, поскольку они не могут подключиться. К этому тоже нужно подготовиться заранее.

Что касается redis, в этом блоге есть хороший пример устойчивых очередей:

Что соответствует официальной рекомендации. Дополнительную информацию можно найти в репозитории github.

Крушение Redis:

  • Как и в случае с rabbitmq, вам также необходимо самостоятельно обрабатывать сбой рабочих, иначе выполняемые задачи будут потеряны.
  • Вы должны провести опрос. Каждому потребителю необходимо каждые X секунд спрашивать производителя, есть ли какие-либо новости.

Это, на мой взгляд, худший кролик.

Заключение

Я остановился на rabbitmq по следующим причинам:

  1. Более подробная официальная онлайн-документация с примерами.
  2. Потребителям не нужно опрашивать производителя.
  3. Обработка ошибок так же проста, как и в Redis.

Имея это в виду, для данного конкретного случая я с уверенностью могу сказать, что redis - худший rabbitmq в этом сценарии.

Надеюсь, это поможет.

person Flame_Phoenix    schedule 09.05.2017

Что касается реализации, они оба должны быть простыми - у них обоих есть библиотеки на разных языках, проверьте здесь redis и здесь rabbitmq. Скажу честно: я не использую javascript, поэтому не знаю, как реализованы или поддерживаются уважаемые библиотеки.

Что касается того, что вы не нашли в учебнике (или, возможно, пропустили во втором), где есть несколько слов о постоянных очередях, постоянных сообщениях и подтверждающих сообщениях) есть несколько хорошо объясненных вещей:

Подтверждений издателя действительно нет в учебнике, но есть пример на github в репозитории amqp.node.

С кроликом mq сообщение перемещается (в большинстве случаев) как это
publisher -> exchange -> queue -> consumer
и на каждой из этих остановок нужно достичь некоторого упорства. Кроме того, если вы доберетесь до кластеров и зеркалирования очередей, вы достигнете еще большей надежности (и, конечно, доступности).

person cantSleepNow    schedule 04.05.2017

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

Можно назвать несколько таких, как disque, bull, kue, amqplib и т. Д.

Документация к ним очень хорошая. Вы можете просто скопировать и вставить и запустить его через несколько минут.

Я использую seneca, и seneca amqp - довольно хороший пример

https://github.com/senecajs/seneca-amqp-transport

person Tuan Anh Tran    schedule 04.05.2017