在高层次上,这是正在发生的事情:
- 我们有两个 SQL Server 2008 R2 SP1 系统(Windows NT 6.1 上的标准版(Build 7601:Service Pack 1))它们运行良好,双向通信没有错误或问题。
- 我们重新启动系统#2,期望在系统#2 不可用时发送给它的任何Service Broker 消息将在系统#1 上排队,直到系统#2 恢复。
- 系统 #2 重新启动,那里的一切正常启动,没有错误。
- 在系统 #1 上为系统 #2 排队的消息仍然在排队;他们永远不会被发送。此外,该对话中的新消息也会排队并且永远不会发送。
- 在新对话中发送的消息传输得很好。
关于从未发送的消息的详细信息:
A. 当系统 #2 关闭时,队列中消息的传输状态显示各种错误,表明它无法与系统 #2 通信,如预期的那样。
B. 系统#2 恢复后不久,这些消息的传输状态变为空白。在此之后,空白状态永远不会改变。
C. 消息堆积的会话处于 CONVERSING/CO 状态。系统视图中没有任何列表明与其他正常工作的队列有任何不同。(如果我能找到任何设置不同的标志,我会知道终止糟糕的对话,但系统没有提供任何线索——除了不断增长的队列深度。)
D. 在系统#2 上永远不会收到消息,因为我的激活存储过程永远不会为这些消息调用。
E. 在 Profiler 中(打开所有 Broker 跟踪类型),良好的对话显示正在记录以下内容:
Broker:Conversation CONVERSING 1 - SEND Message Initiator
Broker:Message Classify 2 - Remote Initiator
[SQL Batch complete; SQL that caused the SEND to occur]
Broker:Remote Message Acknowledgement 1 - Message with Acknowledgement Sent Initiator
Broker:Message Classify 1 - Local Initiator
Broker:Conversation CONVERSING 6 - Received Sequenced Message Target
Broker:Remote Message Acknowledgement 3 - Message with Acknowledgement Received Initiator
Broker:Activation Microsoft SQL Server Service Broker Activation 1 - Start
发送的注定会卡住的消息仅显示这些事件中的前两个:
Broker:Conversation CONVERSING 1 - SEND Message Initiator
Broker:Message Classify 2 - Remote Initiator
据我所知,这就是这些消息所传得的全部内容。没有迹象表明 SQL Server 会再次尝试传输它们。系统#1 认为对话还不错,但系统#2 完全忘记了。系统#1 似乎永远无法解决这个问题。如果我们随后重新启动系统#1,那么一切都会恢复正常,所有消息都按预期流动。
我认为这些消息实际上已经发送,但是确认并没有返回到系统#1。但我没有看到任何备份确认队列的证据。
我们检查了双方的许多典型问题:
双方都启用了代理。2. 所有队列都打开,所有适当的东西都启用(入队、接收)。队列没有中毒。3. 不存在我们所知道的权限问题。4. 我们没有使用即发即弃。5. 我们正在重用对话,正如许多人所建议的那样。(事实上,对话重用是这里的问题!) 6. 我们正在捕获 SQL 异常,按照指示使用事务等。 7. ssbdiagnose 没有返回错误。
当 SQL Server 主机重新启动时,我们预计任何排队的消息最终都会被发送,但事实并非如此。这里发生了什么??