向外扩展消息代理订户,防止出现双重消息

时间:2018-12-16 15:37:51

标签: rabbitmq azureservicebus messagebroker

我正在考虑在发布/订阅模式下使用的经典消息代理(例如RabbitMQ或Azure Service Bus)。

让我们谈谈这个例子:

  

-发布者1(示例订单发送者)

     

-订户A(计费)

     

-订户B(发货)

如果我要扩展一个订户(例如订户B)会发生什么?

确定我会拥有这种组合:

  

-发布者1(示例订单发送者)

     

-订户A(计费)

     

-订户B-节点1(装运)

     

-订户B-节点2(装运)

应该使用哪种模式来防止消息代理将相同的消息发送到订户2的两个节点?

当然,我并不是在引用我作为示例列出的服务的某些API,而是我想像的是当存在消息代理并且某些订户应该扩展时的经典用例。

3 个答案:

答案 0 :(得分:1)

在添加同一逻辑节点的实例时,您是在向外扩展,而不是向上扩展。两家经纪人都支持Competing Consumers pattert,并且在扩展 out 时不需要任何特殊要求。消息将仅由单个实例处理,除非未能及时处理(在Azure Service Bus情况下)或未成功完成。

答案 1 :(得分:1)

我在一家名为Solace的公司工作,我们做消息经纪人。您的用例非常典型,并且很容易构造。正如肖恩所说,这是竞争的消费者。配置方法如下:

由于您的示例消息是 Orders ,所以我假设您不想丢失这些消息,因此需要使用持久消息。在Solace中,当邮件降落在队列中时,它们将保留。因此:

  • 您的发布商1将发布“订单”主题(例如orders/new/[ORDER_ID]
  • 您将配置两个队列(qaqb):
    • 在每个队列上为主题orders/new/*添加订阅
    • 第二个队列将配置为非排他性,从而允许轮流或负载均衡地交付给所有连接的使用者
  • 订户A将绑定到qa,订户B1和B2将绑定到qb

由于发布/订阅机制的原因,每个队列都会收到消息的副本。为了提高效率,Solace中的持久性存储全部基于指针(通过引用计数),因此即使将消息复制到多个队列中,每个消息也只能在磁盘上写入一次。 (不像Rabbit将每个副本都写入磁盘)。

qb添加更多消费者/订户将动态地平衡所有消费者/订户。

答案 2 :(得分:0)

因此,该解决方案看起来像添加一个队列作为主题的订户,以平衡同一服务的多个节点之间的消息。

通过这种方式,我应该事先知道是否要扩展该服务,因为它将改变我的编程模型,以了解如何使用Message Broker客户端API。

-最佳做法是什么?永远不要直接使用对主题的订阅,而要在中间放置一个队列,以便最终在不同节点扩展接收方?

如我所见,Solace提供了一种方法来将队列声明为主题的订阅并使用队列中的消息。那Azure Service Bus和Rabbit MQ呢,我可以用这种方式配置它们吗?

感谢您的耐心