【问题标题】:Need to consume messages in order with high-availability需要按顺序消费消息,高可用
【发布时间】:2015-07-23 11:06:10
【问题描述】:

是否有一种标准设计模式可以让我按顺序使用队列中的消息,但又具有高可用性?

当然,我可以按帐号最后一位数将负载分成单独的队列(顺序仅对每个帐户很重要),这给了我可扩展性,但如果主机处理以“2”结尾的帐号失败,例如,我需要一些东西来承担这个负担。

我认为这种处理有一个标准模式。不幸的是,我无法使消息具有幂等性,因为队列源是由第三方集成造成的。

非常感谢任何想法。

【问题讨论】:

  • 您能澄清一下“按顺序使用队列中的消息吗?”我看到了 2 种可能的解释:#consume 消息按源系统生成的顺序排列,同时保留全局顺序。 #consume 消息在单个帐户的上下文中的顺序。此外,您是否在消息中有序列信息,或者只是假设(单个?)源以某种顺序生成消息并且它们应该以相同的顺序到达。还有一个问题:如果消费者抛出错误会发生什么?队列应该停止还是继续?时机重要还是可以接受延迟。

标签: design-patterns high-availability architectural-patterns


【解决方案1】:

尽管这是几天前的事情,但必须回答一个包含“幂等”一词的问题。不要认为这里一定有设计模式,但我有一个方法。

我会按照您的建议使用单独的工作队列以可扩展的方式处理消息。一个脑残的简单排序阅读器将从第三方队列中读取消息并将消息发送到适当的工作队列。

高可用性部分将与工作队列读取器一起提供。这些中的每一个都有一个好友队列阅读器。每个队列读取器都会定期向其伙伴发送心跳消息。如果好友没有收到消息(或一定数量的消息),它会:

  1. 开始处理它现在死去的好友的队列以及它自己的队列
  2. 通知系统管理员有关死队列读取器的信息

为了防止两个读者碰上同一个队列,当一个死队列被复活时,它会先和它的好友重新建立心跳。一旦好友确认它不再处理恢复队列阅读器的原始队列上的消息,恢复的阅读器将再次开始工作。

您可以通过增加组中好友的数量来获得更多冗余,或者让队列阅读器在其原始好友死亡时建立一个新好友,但这会在阅读器死亡或返回时增加更多复杂性。

解决此问题的一种方法是为每个队列设置一个令牌。读取器只有在拥有令牌时才能读取队列。每个读者将开始拥有一个令牌,并向所有其他读者广播心跳。心跳将包括阅读器当前正在处理的队列的所有令牌。这将为所有读者提供整个系统的图片,而无需集中授权。当读者注意到某个令牌在某个时间范围内没有被广播时,它会在以下情况下认领该令牌:

  1. 在幸存的读者中拥有最少数量的令牌
  2. 或者在平局的情况下,在令牌数量最少的幸存读者中拥有最低的 ID#。

一旦获得令牌,它将开始处理队列,并向系统管理员发送通知。

当阅读器重新上线时,它将收听心跳并重建其系统图。然后它将确定哪个阅读器拥有:

  1. 最多的令牌
  2. 或者在平局的情况下,拥有最高 ID# 的阅读器

复活的读者将认领其他读者列表中的最后一个令牌。一旦其他读取器确认声明并且不再处理由令牌表示的队列,恢复的读取器将再次开始处理队列。

这种方法的一个可能优点是不需要一对一的读取器到队列关系。它允许您创建任意数量的有意义的队列,并找到相应数量的可以处理负载的阅读器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多