1

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

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

  • 输入大概是每两秒之后,(时间戳是正确的我已经验证过了)
  • 如果我断开接收器一段时间,消息开始在 Azure 上针对订阅排队。
  • 然后如果我再次连接接收器,接收代码接收消息很快,但没有保持顺序?
  • 但是,如果我保持客户端连接,则按顺序接收消息(两秒后有 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

任何人都可以解释为什么会这样吗?这对我来说有点混乱?

4

2 回答 2

3

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

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

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

服务总线文档

以下是一些相关的堆栈溢出帖子,可能会对您有所帮助。

如何使用 Azure 服务总线主题完成 FIFO

如何保证 azure queue FIFO

编辑

此链接包含有关 FIFO 的一些详细信息

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

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

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

于 2017-05-23T14:24:03.510 回答
3

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

  1. 接收者一次只会处理一个会话
  2. 并发处理是不可能的,无论处理时间如何,您都将只处理一条消息。
  3. 发件人需要为每条消息分配会话 ID。

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

于 2017-05-23T15:22:07.507 回答