Azure 服务总线主题订阅者接收订单

Posted

技术标签:

【中文标题】Azure 服务总线主题订阅者接收订单【英文标题】:Azure Service Bus Topic Subscriber receiving order 【发布时间】:2017-10-23 12:41:10 【问题描述】:

我正在使用 azure 服务总线主题作为我的解决方案的消息代理。根据我对每个订阅的理解,Azure 消息总线会保留一个虚拟队列,因此在接收端消息的顺序不应受到干扰。

但实际上它有点不同,在我的场景中

大约每两秒输入一次,(时间戳正确我已经验证过了) 如果我断开接收器一段时间,消息会开始在 Azure 上针对订阅排队。 那如果我再次连接receiver,接收代码接收消息很快,但顺序没有保持? 但是,如果我保持客户端连接,则按顺序接收消息(两秒后收到 1 条消息)

接收代码

SubscriptionClient Client = SubscriptionClient.CreateFromConnectionString(connectionString, topicname, subscription_name);

                // Configure the callback options.
                OnMessageOptions options = new OnMessageOptions();
                options.AutoComplete = false;
                options.AutoRenewTimeout = TimeSpan.FromMinutes(1);

                // Callback to handle received messages.
                Client.OnMessage((message) =>
                
                    try
                    
                        // Process message from queue.
                        string payload = message.GetBody<string>();
                        var myData = JsonConvert.DeserializeObject<MyData>(payload);
                        if(myData != null)
                        

                            //Timestamp is not in order, when I connect after few minutes
                            Debug.WriteLine("SBC ==> " + myData.Timestamp);

                        
                        // Remove message from queue.
                        message.Complete();
                    
                    catch (Exception)
                    
                        // Indicates a problem, unlock message in queue.
                        message.Abandon();
                    
                , options);

输出

SBC ==> 5/23/2017 1:06:43 PM
SBC ==> 5/23/2017 1:06:45 PM
SBC ==> 5/23/2017 1:07:23 PM
SBC ==> 5/23/2017 1:07:19 PM
SBC ==> 5/23/2017 1:07:27 PM
SBC ==> 5/23/2017 1:07:07 PM
SBC ==> 5/23/2017 1:06:49 PM
SBC ==> 5/23/2017 1:07:47 PM
SBC ==> 5/23/2017 1:06:47 PM
SBC ==> 5/23/2017 1:08:03 PM
SBC ==> 5/23/2017 1:06:55 PM
SBC ==> 5/23/2017 1:06:51 PM
SBC ==> 5/23/2017 1:07:03 PM
SBC ==> 5/23/2017 1:07:51 PM
SBC ==> 5/23/2017 1:06:57 PM
SBC ==> 5/23/2017 1:07:05 PM
SBC ==> 5/23/2017 1:07:39 PM
SBC ==> 5/23/2017 1:07:43 PM
SBC ==> 5/23/2017 1:06:59 PM
SBC ==> 5/23/2017 1:07:09 PM
SBC ==> 5/23/2017 1:06:53 PM
SBC ==> 5/23/2017 1:07:33 PM
SBC ==> 5/23/2017 1:07:25 PM
SBC ==> 5/23/2017 1:07:57 PM
SBC ==> 5/23/2017 1:08:13 PM

谁能解释一下为什么会这样?对我来说有点困惑?

【问题讨论】:

【参考方案1】:

就像@NPhillips 所说,您需要使用 ASB 的 Message Sessions 功能来实现 FIFO 行为。这意味着有几件事情需要注意:

    接收者一次只会处理一个一个会话 无法进行并发处理,无论处理时间如何,您都只能处理一条消息。 发件人需要为每条消息分配会话 ID。

最好的示例和解释是 ASB 团队在 GitHub here 上发布的示例。

【讨论】:

【参考方案2】:

虽然 azure 服务总线将自身提供为 FIFO(先进先出),但这仅在不间断会话期间才真正起作用。正如您所经历的:

但是,如果我保持客户端连接,则按顺序接收消息

要解决此问题,您可以使用不同的模式。 在下面的链接中查看 ReceiveAndDelete 和 PeekLock 模式。

Service Bus Docs

这里有一些相关的堆栈溢出帖子可能会对您有所帮助。

How to accomplish FIFO with Azure service bus topics

How to gurantee azure queue FIFO

编辑

This link contains some details on the FIFO

以下是该文档的引用,它指定您需要使用消息传递会话才能获得 FIFO。

服务总线队列中的保证 FIFO 模式需要使用消息传递会话。如果应用程序在处理以 Peek & Lock 模式接收的消息时崩溃,则队列接收器下一次接受消息会话时,它将在其生存时间 (TTL) 期限到期后从失败的消息开始。

实现消息会话的文档似乎相当缺乏,但据我了解,它来自MessageSession 类,它是AcceptMessageSession方法

【讨论】:

感谢您的 cmets,您能否参考 MSDN 上描述此 The problem you are having is that when you disconnect the receiver the messages that time out begin to retry after a set amount of time. This causes them to lose the order they were sent in. 的一些文档?这真的很有帮助。 将添加到答案中。 已删除您从问题中引用的部分,因为我无法为其提供可靠的来源。不久前我遇到了这个问题,这就是我对这个问题的理解,但当然,如果没有文档支持,我的话就没什么意义了。您可能会发现这篇博文很有用,但我怀疑它有点过时了:ben-morris.com/…

以上是关于Azure 服务总线主题订阅者接收订单的主要内容,如果未能解决你的问题,请参考以下文章

Service Fabric Actor 订阅 Azure 服务总线主题

每个 Web 服务器的 Azure 服务总线主题订阅

Azure 服务总线有序处理消息

Azure 服务总线 http 与 websocket

在 web api 中接收服务总线消息队列/主题

如何删除 Azure 服务总线主题上的死信消息