如何确保与多个竞争消费者的信息幂等性?

时间:2009-11-03 17:38:55

标签: messaging idempotent

我有多个分布式竞争消费者,每个消费者都从同一个(事务性)队列中拉出消息。我想将每个消费者实现为Idempotent Receiver,因此即使重复到达,我也不会多次处理同一消息(跨所有消费者)。如何与多个消费者实现这一目标?

我的第一个想法是以某种方式为每个消息生成一个连续的序列号,然后将它们放入队列,然后使用共享数据库表来协调消费者之间的工作。即使用者#1处理msg#1然后将一行写入DB表,说'msg#1已处理'(希望它在数据库中以确保持久性)。当消费者准备处理消息时,它会查看队列中可用的下一个消息,查询共享数据库表并确定这是否是按顺序的下一个消息。如果是这样,它会将其从队列中拉出来。如果没有,它会忽略它。

通过这种方式,我只需要存储最后处理的消息(因为所有消息都有一个连续的序列号),我不需要使用一个缓冲区来存储通过协商的“窗口”收到的所有消息的ID大小,并且消息总是串行处理(这是我想要的这种情况)。

只是好奇是否有更好的方法?我担心每当我需要处理消息时查询数据库的成本。

如果答案是“这取决于框架”,那么我就会考虑到MSMQ

3 个答案:

答案 0 :(得分:1)

幂等接收者的观点是,如果消息被多次处理则无关紧要。因此,幂等接收者不需要重复检测到消息是重复的,他们可以像往常一样简单地处理它......

所以要么你的接收者不是幂等的,要么你不必要地担心......

答案 1 :(得分:0)

安德鲁 -

另一个选择是查看队列如何处理消息。有一些队列在消费者接收消息后删除消息。这是队列的典型行为,找到具有此类功能的队列应该不难。这应该为您提供一个简单的解决方案,而不是为每个消费者构建一种方法,以确保他们不会收到已被其他消费者处理过的消息。

最佳, 亨利

答案 2 :(得分:0)

我通过确保每条消息都有GUID或其他唯一标识符,然后将其记录在您更改持久性存储中的状态的同一事务中来完成幂等消息。

对于每条消息,您现在可以检查持久性存储中是否存在唯一ID。

如果存在唯一ID,您知道它之前已处理过,并且状态更改在同一事务中保留。

如果唯一ID不存在,则表示它从未被处理过。

如果两个消费者处理相同的消息,因为您存储已处理的唯一ID的表具有唯一约束,当两个消费者提交其事务时,其中一个必须失败并回滚所有它的变化而另一个会成功。