首页 > 解决方案 > 为什么即使没有消息排队,我的 Azure 服务总线会话仍然存在?

问题描述

我有一个启用会话的 Azure 服务总线队列。

我有一些使用 WindowsAzure.ServiceBus NuGet 包的代码。(Microsoft.ServiceBus.Messaging 程序集)

在处理两个或三个会话 ID 的多条消息后,使用 BrokeredMessage.Complete() 将这些消息标记为完整,并在每个会话上调用 MessageSession.Close()(我已经验证这正在发生) - 所有消息都被消耗并且队列很清楚。

但是,当我随后调用 QueueClient.GetMessageSessions() 时,它会返回 2 个会话,就好像它们没有完成一样。

在我的一生中,我找不到答案:是否有人知道任何条件/场景会在队列中消耗所有消息之后很久才能在 Azure 服务总线中保持会话“打开”。至少就 QueueClient.GetMessageSessions() 调用而言?

我试图在单独的测试中重现该问题,但没有这样做。产生了几条随机消息,进行了混乱测试,我尝试将会话标记为已关闭,而不是将它们标记为已关闭,将它们标记为在错误的时间关闭。尽管如此,每次我启动的测试队列都能很好地处理它,并且在“混乱”测试结束时返回当前的会话数:0。

换句话说,我无法重现这一点。

我反编译了 Microsoft.ServiceBus.Messaging DLL,以查看从库的角度调用 QueueClient.GetMessageSessions() 时实际发生的情况:它实际上将 TCP/IP GetMessageSessions 命令直接发送到 Azure 服务总线,并从那里接收响应。所以这不是 QueueClient 实例包装调用并做一些棘手的事情来推断有多少会话的地方。此信息直接来自 Azure 服务总线。

我假设即使我错过了对 MessageSession.Close() 的调用(这已通过我的测试得到证实),如果队列中没有消息使其具有锁上。特别是在队列配置中的任何过期日期/时间等待很久之后。

即使在第二天,我仍在阅读 QueueClient.GetSessions() 中针对该队列的 2 个会话。

标签: sessionazureservicebus

解决方案


哦,我终于弄清楚发生了什么。

在我的“中断”代码中,我使用 MessageSession.SetState(Stream stream) 设置了一些会话状态。我忽略了在我的测试中做同样的事情,我无法重现这个问题。一旦我在测试中开始这样做,问题就会重现。

摘要:显然,当您在会话上运行 MessageSession.SetState(Stream stream) 并且在完成会话后不清除状态时,即使在技术上关闭,QueueClient.GetMessageSessions() 调用仍将返回这些会话- 就我而言,至少几天后。

至少对于今天的 Azure 服务总线,如果您不希望它出现在 QueueClient.GetMessageSessions() 响应中,则必须从会话中清除状态。

我还没有弄清楚这些会话需要多长时间才能从结果中“消失”,如果有的话,如果有人选择不清除状态。我知道在我的情况下已经两天了,我仍然有会议出现。

另请注意:您不能调用 QueueClient.GetMessageSessions() 然后遍历并调用 MessageSessions.SetState 。此调用返回的会话实际上只是其下的一个 SessionBrowser 对象,因此该方法会引发异常。必须在初始 SessionHandler 中清除状态。


推荐阅读