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

新手上路,请多包涵

背景

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

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

客观的

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

消息的排序不是必须的。

问题

根据我的研究,RabbitMQ 是这种场景的正确选择:

然而,尽管 RabbitMQ 有一个关于 发布和订阅者 的教程,但是这个教程并没有向我们展示持久队列,也没有提到 确认,我认为这是确保消息被传递的关键。

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

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

问题

  1. 对于这个用例,哪种解决方案最容易实施? (Redis 方案还是 RabbitMQ 方案?)
  2. 请提供您认为最好的示例的链接!

原文由 Flame_Phoenix 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 393
2 个回答

背景

我最初想要发布和订阅消息和队列持久性。

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

  • 此模式不关心是否收到消息。发布者只是将消息散开,如果有任何订阅者在收听,那很好,否则它不在乎。

事实上,从我的需求来看,我需要更多的工作队列模式,甚至是 RPC 模式。

分析

人们说两者都应该很容易,但这确实是主观的。

RabbitMQ 总体上有更好的官方文档,在大多数语言中都有清晰的示例,而 Redis 信息主要在第三方博客和稀疏的 github 存储库中——这使得它很难找到。

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

通过混合这两者,我能够让一个发布者向多个消费者发送可靠的消息——即使其中一个失败了。消息不会丢失,也不会被遗忘。

rabbitMQ 的垮台:

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

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

遵循官方 推荐。您可以查看 github 存储库 以获取更多信息。

redis的垮台:

  • 和rabbitmq一样,你也需要自己处理worker crash,否则正在进行的任务会丢失。
  • 你必须做投票。每个消费者都需要每隔 X 秒向生产者询问是否有任何消息。

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

结论

由于以下原因,我最终选择了 rabbitmq:

  1. 更强大的官方在线文档,带有示例。
  2. 消费者无需轮询生产者。
  3. 错误处理与在 Redis 中一样简单。

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

希望能帮助到你。

原文由 Flame_Phoenix 发布,翻译遵循 CC BY-SA 3.0 许可协议

关于实施,它们都应该很容易——它们都有各种语言的库,请在此处查看 redis 和在此处查看 rabbitmq 。我在这里说实话:我不使用 javascript,所以我不知道受人尊敬的库是如何实现或支持的。

关于您在本教程中没有找到的内容(或者可能 在第二个 教程中遗漏了一些关于持久队列和持久消息以及确认消息的词),有一些很好的解释:

发布者确认确实不在教程中,但 在 amqp.node 的 repo 中的 github 上有一个示例

使用 rabbit mq 消息(在大多数情况下)像这样传播

publisher -> exchange -> queue -> consumer

在这些站点中的每一个站点上,都需要实现某种持久性。此外,如果您使用集群和队列镜像,您将获得更高的可靠性(当然还有可用性)。

原文由 cantSleepNow 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题