Azure Service Bus主题订阅者接收订单

时间:2017-05-23 13:56:27

标签: c# azure message-queue messagebroker azure-servicebus-topics

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

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

  • 输入大约是每两秒一次,(时间戳是正确的,我已经验证了)
  • 如果我将接收器断开一段时间,则消息将开始在Azure上与订阅进行排队。
  • 然后,如果我再次连接接收器,接收代码会很快收到消息,但订单没有维护?
  • 但是如果我保持客户端连接,则按顺序接收消息(两秒钟后发送一条消息)

接收代码

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

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

2 个答案:

答案 0 :(得分: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。

  

Service Bus队列中的保证FIFO模式需要使用消息传递会话。如果应用程序崩溃,同时处理在Peek&amp ;;中收到的消息。锁定模式,下次队列接收器接受消息传递会话时,它将在失效消息的生存时间(TTL)到期后开始。

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

答案 1 :(得分:2)

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

  1. 接收方一次只会处理单个会话
  2. 无法进行并发处理,无论何时处理,您都可以使用单个消息。
  3. 发件人需要为每封邮件分配会话ID。
  4. 最佳样本和解释将是ASB团队在GitHub上发布的here