如何使用Azure Service Bus分区队列/主题支持FIFO消息排序?

时间:2015-01-23 16:25:23

标签: azure servicebus azureservicebus

我认为使用分区队列和主题的权衡是不再保证消息排序。

由于消息默认是循环发送到每个片段/分区,因此这意味着不再保证消息排序。任何人都可以确认是否是这种情况吗?

如何在从分区队列接收交易时保证消息排序。

使用分区队列/主题支持FIFO消息排序的唯一方法是使用会话吗?我会假设同一会话/分区密钥的所有消息至少都会传送FIFO?

3 个答案:

答案 0 :(得分:7)

我在博客文章中发现了这一点。

希望它有所帮助!

Partitioned Service Bus Queues and Topics

  

的SessionID。如果消息设置了SessionId属性,则Service Bus使用SessionId属性作为分区键。这样,属于同一会话的所有消息都将分配给同一个片段,并由同一个消息代理处理。这允许Service Bus保证消息排序以及会话状态的一致性。

答案 1 :(得分:2)

仅仅因为您没有使用分区队列或主题并不意味着您将获得FIFO。如果您有多个读取器或者执行异步操作,那么除非您使用Sessions,否则您将无法获得FIFO,如上所述。请使用会话。

答案 2 :(得分:0)

在上面的答案中,关于FIFO缺少一个重要的观点。

当消息进入未启用分区的主题/队列时,将观察到FIFO用于消息传递*。

在主题/队列上启用分区并且使用SessionId作为分区键时,消息不再保证彼此之间是FIFO ,它们只是

保证相对于它们划分到的分区是FIFO。

有趣的是,如果您对同一订阅/队列的订阅者数量较少,则分区通常会产生一些有趣的副作用,因为分区阅读器的分配是按循环方式进行的,并且如果分区数大于订阅者,您会看到消息被饿死(需要SB团队验证,这是我自己进行的测试的经验,因为我的消息被饿死了)。


*如@Dan Rosanova上面指出的那样,如果您具有异步处理或多个读取器,则不能保证消息处理是FIFO,而是消息的顺序分配给处理器的将是FIFO。

当您使用会话消息处理程序(需要填充SessionId)时,您将采取进一步的措施,并确保按会话顺序对消息进行处理消息处理程序将对SessionId + MessageId进行锁定,而不仅是对MessageId进行锁定,从而确保同一会话中的其他消息不会被其他处理器接收。