发布/订阅可靠消息:Redis VS RabbitMQ

背景

我正在制作一个发布/订阅典型应用程序,发布者向消费者发送消息。

发布者和消费者在不同的机器上,它们之间的连接偶尔会中断。

目的

这里的目标是确保无论连接发生什么事情,或者机器本身,发布者发送的消息总是消费者接收。

消息的sorting不是必须的。

问题

根据我的研究,RabbitMQ是这种情况下的正确select:

  • Redis将RabbitMQ作为Logstash和elasticsearch之间的数据代理/消息传递系统

然而,尽pipeRabbitMQ有一个关于发布和订阅的教程,但本教程不会将我们介绍给持久队列,也不会提到确认我认为是确保消息传递的关键。

另一方面,Redis也能做到这一点:

  • http://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/

但我找不到任何正式的教程或示例,而我目前的轻描淡写导致我相信,持久的队列和消息确认必须由我们来完成,因为Redis主要是内存数据存储而不是像RabbitMQ这样的消息代理。

问题

  1. 对于这个用例,哪个解决scheme最容易实现? (Redis解决scheme还是RabbitMQ解决scheme?)
  2. 请提供一个与您认为最好的例子的链接!

关于实施,他们都应该很容易 – 他们都有各种语言的图书馆,在这里检查redis和这里为rabbitmq 。 我只是在这里诚实:我不使用JavaScript,所以我不知道如何实施或支持受尊重的库。

关于你在教程中没有find的东西(或者在第二个关于持久队列和持久消息和确认消息的文字中错过了 ),有一些很好的解释:

  • 关于持久性
  • 关于确认 (与问题中提供的链接相同,只是为了清晰起见在此处列出)
  • 关于可靠性

发布者证实确实没有在教程中,但在amqp.node的回购中有一个github上的例子 。

随着兔子mq消息传播(在大多数情况下)这样的
publisher -> exchange -> queue -> consumer
在这些站点的每一个站点都有某种持久性要实现。 另外,如果您获得群集和队列镜像,您将获得更高的可靠性(当然还有可用性)。

背景

我原本希望发布和订阅消息和队列持久性。

这在理论上并不完全适合发布和订阅:

  • 这种模式并不在乎是否收到消息。 发行商只是发出消息,如果有任何用户倾听,好,否则它不在乎。

确实,看我的需求,我需要更多的工作队列模式,甚至RPC模式。

分析

人们说这两个都应该很容易,但那真的是主观的。

RabbitMQ总体上有更好的官方文档,大多数语言都有清晰的例子,而Redis的信息主要在第三方博客和稀疏的github回购 – 这使得它很难find。

至于例子,RabbitMQ有两个例子可以清楚地回答我的问题:

  • 工作队列
  • RPC示例

通过混合两者,我可以让发行商向多个消费者发送可靠的消息 – 即使其中一个失败。 消息不会丢失,也不会被遗忘。

rabbitMQ的倒台:

  • 这种方法最大的问题是,如果一个消费者/工作者崩溃,你需要自己定义逻辑,以确保任务不会丢失。 发生这种情况的原因是,一旦任务完成,使用来自“工作队列”的持久队列的RPC模式,服务器将继续向工作人员发送消息,直到它再次恢复。 但是工作人员并不知道它是否已经从服务器读取了答复,所以它会从服务器收到几个ACK。 为了解决这个问题,每个工作者消息需要有一个ID,保存到磁盘(如果失败)或者请求必须是幂等的。
  • 另一个问题是,如果连接丢失,客户端因无法连接而出现错误。 这也是你必须提前准备的。

至于redis,它在这个博客里有一个很好的持久队列的例子:

这是官方的build议 。 你可以检查github回购更多的信息。

redis的崩溃:

  • 与rabbitmq一样,您也需要自己处理工作人员崩溃,否则任务正在进行。
  • 你必须做投票。 每个消费者需要每隔X秒向生产者询问是否有消息。

在我看来,这是一个最糟糕的rabbitmq。

结论

我结束了与rabbitmq出于以下原因:

  1. 更强大的官方在线文档,附带示例。
  2. 消费者无需调查生产者。
  3. error handling就像在redis中一样简单。

考虑到这一点,对于这个特定的情况,我有信心说在这种情况下redis是最差的。

希望能帮助到你。

我认为它们都很容易使用,因为有很多为它们开发的库。

有几个名字,如disque,公牛,kue,amqplib等…

他们的文件是相当不错的。 你可以简单的复制和粘贴,并在几分钟内运行。

我使用塞内卡和塞内卡amqp是一个很好的例子

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