消息总线:发件人必须等待来自多个收件人的确认
Posted
技术标签:
【中文标题】消息总线:发件人必须等待来自多个收件人的确认【英文标题】:Message bus: sender must wait for acknowledgements from multiple recipients 【发布时间】:2013-04-01 10:51:47 【问题描述】:在我们的应用程序中,发布者创建一条消息并将其发送到主题。
当所有主题的订阅者都确认消息时,它需要等待。
它不会出现,消息总线实现可以自动执行此操作。因此,我们倾向于让每个订阅者在完成后向客户发送他们自己的新消息。
现在,客户端可以接收所有此类消息,并且当它从每个目的地收到一条消息时,可以执行它必须执行的任何清理操作。但是,如果客户端(发送方)在确认流中途崩溃了怎么办?为了处理这样的不幸,我需要在客户端(重新)实现总线已经实现的东西——保存传入的确认,直到我得到足够的确认。
我不相信,我们的需求是如此深奥——您将如何处理这种情况,发件人(发布者)必须等待来自多个收件人(订阅者)的确认?有点像从每个订阅者向邮件列表请求(并等待)回执...
如果重要的话,我们正在使用 RabbitMQ。谢谢!
【问题讨论】:
【参考方案1】:您正在寻找的功能听起来像是一种消息传递解决方案,可以跨消息的发布者和订阅者执行事务。在 Java 世界中,JMS 指定了此类事务。 JMS 实现的一个示例是HornetQ。
RabbitMQ 不提供此类功能,但这样做是有充分理由的。 RabbitMQ 的构建是为了非常健壮并同时表现得像地狱一样。您描述的事务行为只有以合理的性能损失为代价才能实现(特别是如果您想保持出色的稳健性)。
使用 RabbitMQ,确保消息被成功消费的一种方法实际上是在消费者端发布一条应答消息,然后由原始发布者消费。这可以通过RabbitMQ's RPC procedure calls 实现,这可能会帮助您为您的问题设置找到一个干净的解决方案。
如果(原始)发布者在收到所有答案之前崩溃,您可以假设所有未完成的答案仍在代理中排队。因此,您必须以能够恢复处理那些留下的消息的方式构建您的发布者。这可能并非易事。
最后,我推荐以下解决方案: 设计您的生产组件,使您可以使用与原始发布者分离的一个或多个专用答案消费者来使用答案。
此解决方案的好处是:
-
原始发布者可以独立于消费者成功完成其任务
原始发布者独立于消费者的可用性和速度
原始发布者的实现要简单得多
在崩溃场景中,答案消费者可以继续处理答案
现在来说一个更笼统的观点:消息传递的主要好处之一是代理将应用程序组件解耦。在 AMQP 中,这是通过交换和绑定实现的,允许您将消息分发逻辑从应用程序移动到配置的中心点。
如果您向客户端添加 RPC 样式的调用,那么您的组件很可能再次紧密耦合,这意味着如果使用组件之一失败/不可用/太慢,则发布组件将失败。这正是您想要避免的。否则,你为什么要拆分组件呢?
我的建议是,您的应用程序设计方式应使发布者可以尽可能独立于消费者的成功来完成他们的任务。反向通道应该是一个例外情况,并以所描述的非耦合方式实现。
【讨论】:
谢谢,克里斯。是的,这就是我们所做的:每个消费者都将自己的消息“返回”到一个单独的队列,该队列由原始发布者指定。它有效——而且,也许比使用 RPC 更好,因为这些确认的聚合器不必与确认消费者同时在线。但是聚合器的代码重新实现了代理中已经找到的一些功能(例如重启容错),我希望利用后者来达到目的......以上是关于消息总线:发件人必须等待来自多个收件人的确认的主要内容,如果未能解决你的问题,请参考以下文章
获取由消息发送者的“dbus_request_name”设置的总线名称