我使用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
任何人都可以解释为什么会这样吗?这对我来说有点混乱?
答案 0 :(得分:2)
虽然azure服务总线将自己设置为FIFO(先进先出),但这只能在不间断的会话期间正常工作。正如您所经历的:
但是,如果我保持客户端连接,则按顺序接收消息
要解决此问题,您可以使用其他模式。 请看下面的链接中的ReceiveAndDelete和PeekLock模式。
以下是一些可能对您有帮助的相关堆栈溢出帖子。
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行为。这意味着需要注意的几件事情:
最佳样本和解释将是ASB团队在GitHub上发布的here。