我还在我的博客上发布了这个问题: http://www.sqldiablo.com/2012/04/15/service-broker-broker-alwayson-availability-groups-odd-transmission-queue-queue-behavior/.

在过去的几个月中,我一直在从事一个项目,该项目将利用服务经纪人和EwswandOn可用性小组来满足我工作的公司的一些HA和DR目标(更多信息: http://www.sqldiablo.com/service-broker-replication/)。就在最近,我能够在我的开发实验室中实现完整的解决方案,并指出我们网站的实例。当我们在数据库和网站上锻炼一些扭结以使两者与我的服务经纪复制项目合作,但当服务经纪人与EwsectOn可用性小组一起使用时,我开始注意到一些奇怪的行为,我想在其中写博客。尝试查看其他人是否已经看到这个问题,并可能有一个想法解决问题。

设置:

我有一个运行6个Windows Server 2008 R2 VM(BTDEVSQLVM1-BTDEVSQLVM6)的Hyper-V主机。将VMS分组为带有节点和文件共享法定的2节点WSFC。我已经在每个VM上安装了独立的SQL 2012开发人员版本实例,并在每个群集上创建了一个带有侦听器的可用性组(SBREPLDISTIB,SBREPL1和SBREPL2)。

出于此博客文章的目的,我将重点关注SBREPL1和SBREPLDISTIB之间的沟通。下面的插图显示了对话的每一方面的服务经纪对象:

(我是新手,还不能发布图像,所以请在上面的URL上查看我的博客以获取图像)

服务经纪端点和路线已设置 这篇MSDN文章.MSDB中的SBREPL_RECEIVE路由适用于本地服务器的服务(// sbrepldistrib上的sbrepldistrib/sbrepl和// sbrepl1/sbrepl1上的sbrepl1/sbrepl1),并指向本地实例。 SBREPL_SEND在sbrepl1映射服务上// sbrepldistrib/sbrepl到tcp:// sbrepldistrib:4022,SBREPL_SEND_SBREPL1在sbrepldistrib上的SBREPL_SEND_SBREPL1路由是SBRepldistrib的SBRepll1映射的SBRepldistrib。

预期行为:

我对服务经纪如何处理消息发送和接收的理解是如此(这是非常简单的。在Klaus Aschenbrenner的书“ Pro SQL Server 2008 Service 2008 Service Broker”中,有关此过程的详细信息很多):

  1. 启动器应用程序会创建一条消息(在这种情况下,XML形成良好)
  2. 如果在对话状态中的启动器服务与目标服务之间存在现有的对话对话,则该应用程序可以简单地在现有对话句柄上发送消息。否则,启动器应用程序应开始在启动器服务和目标服务之间进行对话对话,并在该对话句柄上发送消息。
  3. 该消息放在SYS.Transmission_queue系统表中,服务代理开始尝试将消息传递给目标服务。
  4. 服务经纪人寻找合适的路线和远程服务绑定,并使用它们来确定要连接的地址以传递消息。
  5. 服务经纪人打开与目标,身份验证的连接,并将消息传递给目标服务经纪人。
  6. Target Service Broker试图对消息进行分类并确定将要处理该消息的本地服务(为此使用MSDB数据库中的路由数据)。
  7. 目标服务经纪人将消息传递到目标服务队列
  8. 一旦消息成功地传递到目标队列,目标服务经纪人就会将路由信息返回给发起人,并试图提供确认已收到消息的确认。
  9. 发起者的服务经纪人接收确认,并在MSDB中使用路由信息来确定确认的本地服务。
  10. 成功将确认路由到启动服务后,然后将消息从SYS.Transermiss_queue System表中删除。
  11. 如果发起者未收到收到消息的确认,它将定期重试将消息传递给目标。如果目标已经收到消息,它将仅放弃任何额外的送货重试,并为其发送确认。

奇怪的行为:

步骤11是我看到服务经纪人和EwswandOn的一些非常奇怪的行为。我看到消息传递到目标并成功处理的消息,我还看到确认被发送回发起人并接收到。但是,该消息仍保留在sys.transmission_queue中,好像未收到确认。为了使事情变得更加奇怪,服务经纪人并没有像我期望的那样重新传达消息,如果未收到确认。取而代之的是,该消息仅保留在sys.transmission_queue中,并且随着新消息的发送,它们被传递,确认,并且它们也保留在sys.transmission_queue中。在我看来,服务经纪人正在获得确认,因此停止试图传递该消息,但由于某种原因而没有将其从sys.transmission_queue中删除。这些消息的传输_status仍然空白,这应该表明服务经纪人尚未尝试交付它们。

我检查了服务队列上的保留设置,并将其设置为关闭,但这只能影响服务队列而不是SYS.Transmission_queue。我还使用SQL Profiler追踪了对话的两面,并且能够看到发送消息以及发送回启动器并获得接收的消息(请参阅本文末尾的XML跟踪数据)。

不过,一件奇怪的事情确实在痕迹中跳了出来。我注意到双方似乎对TCP连接有些困惑,因为消息是从节点本身的IP地址发送的,而服务路由和消息本身则指向AG侦听器的名称/IP。这种混乱似乎导致双方关闭两种服务之间的现有连接,并创建一个新的连接以传达消息或确认。我不确定这是否正常,还是与为什么无法正确处理确认的原因有任何关系,但这是我唯一可以看到的可能解释奇怪行为的事情。

寻求帮助:

目前,除了用双方的清理手动结束对话之外,我还没有解决此消息保留问题的解决方案,这并不是我真正想做的。如果您对为什么会发生这种情况或我能做什么有任何想法,请给我发表评论,让我知道。如果您希望我提供有关我的设置或有关问题的任何其他信息,请在评论中告诉我。如果/当我找到解决此问题的解决方案时,我将对本文发布后续行动。

跟踪数据:

请参阅我的博客文章(URL是在问题的开头)。

有帮助吗?

解决方案

在过去的几个月中,我一直与Microsoft的产品支持团队合作,他们在SQL Server 2012中认识到有关此问题的两个错误。作为SQL Server 2012的下一个服务包的一部分,他们将为这些错误发布补丁程序。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top