路由和消息传递故障排除

本节提供了解决与路由和消息传递相关的常见问题的建议。

技术:诊断消息传递

如果消息在两个服务间不能成功传递,可以使用 ssbdiagnose 实用工具生成会话的运行时报告。运行时报告将显示会话操作遇到的任何错误。如果遇到错误,ssbdiagnose 还会分析服务之间的配置并报告所发现的任何配置问题。有关详细信息,请参阅 ssbdiagnose 实用工具

问题:消息留在传输队列中

确保在数据库中激活了 Service Broker 消息传递。sys.databasesis_broker_enabled 列显示 Broker 消息传递是否已激活,如下例所示:

SELECT is_broker_enabled FROM sys.databases
WHERE database_id = DB_ID() ;

Broker 消息传递可以停用,以防止将消息误传到其他数据库中。有关 Service Broker 消息传递的详细信息,请参阅 管理 Service Broker 标识。有关如何激活 Service Broker 消息传递的详细信息,请参阅如何在数据库中激活 Service Broker 消息传递 (Transact-SQL)

如果 Service Broker 消息传递处于活动状态,请在 sys.transmission_queue 目录视图中检查消息的 transmission_status 列。常见错误消息如下:

消息

说明

无服务路由。

Service Broker 找不到通向指定服务的路由。

无法访问目标 Service Broker。

Service Broker 无法将消息传递到目标 Service Broker。

传输层不可用。

实例中不存在 Service Broker 端点,或者 Service Broker 端点没有成功启动。

目标队列已禁用。

目标服务所使用的队列的 STATUS 选项设置为 OFF。Service Broker 不会将新消息添加到 STATUS 为 OFF 的队列中。

接收数据时出错: '10054 (现有连接已被远程主机强行关闭。)'。

会话的远程端接受了 TCP/IP 连接,但在消息发出之前关闭了该连接。

(无)

Service Broker 尚未尝试发送消息。如果 enqueue_time 列显示消息已在队列中很长时间,则可能未在数据库中激活 Service Broker 消息传递。

问题:路由存在,传输状态显示没有用于服务的路由

下面列出了导致此问题最常见的原因:

  • SEND 语句在不存在能够成功传递该消息的路由时创建消息。

  • 然后创建了这样的路由,但 Service Broker 尚未尝试重新发送该消息。

有关重试的详细信息,请参阅 Service Broker 路由和网络

确保消息中指定的服务名称与路由中指定的服务名称完全匹配。Service Broker 将进行逐字节二进制比较来匹配服务名称。如果存在指定了服务名称的路由,可以运行以下查询来比较名称:

SELECT N'No Exact Match' = tq.to_service_name
FROM sys.transmission_queue AS tq
WHERE NOT EXISTS
    (SELECT remote_service_name
     FROM sys.routes AS routes
     WHERE tq.to_service_name = routes.remote_service_name) ;
注意注意

即使有的服务名称与路由不匹配,也有可能出现在结果集中。未指定服务名称的路由 (remote_service_name = NULL) 将匹配任何消息所用的服务名称。

有关 Service Broker 路由的详细信息,请参阅 Service Broker 路由

如果消息指定了 Broker 实例标识符,请确保路由指定了相同的 Broker 实例标识符,或者路由根本没有指定 Broker 实例标识符。

请检查路由是否尚未过期。sys.routes 目录视图的生存期列包含路由的过期日期和时间。

问题:传输状态显示无法访问目标 Service Broker

目标不接受消息。这可能指示指定的服务名称与目标 SQL Server 实例承载的服务的名称不匹配。它还可能指示目标不包含用于该服务的路由。若要解决此问题,请检查目标的路由和服务配置。

问题:传输状态显示传输层不可用

请验证 Service Broker 端点存在。如果端点不存在,请创建一个端点。如果端点存在,请验证端点的状态为 STARTED。有关详细信息,请参阅 Service Broker 端点。有关如何创建端点的详细信息,请参阅如何激活 Service Broker 网络 (Transact-SQL)

问题:传输状态显示“现有连接被远程主机强行关闭”

传输安全设置可能配置不正确,或路由的 TCP/IP 地址指定了非 Service Broker 服务所用的端口。

注意注意

路由中指定的端口必须与远程数据库引擎实例上的 Service Broker 端点所用的端口相对应。Service Broker 使用 Service Broker 通信协议来传输消息,而不使用用于传输 Transact-SQL 批处理和结果的表格格式数据流协议。因此,Service Broker 端点使用的端口与用于传输 Transact-SQL 的端口不同。

检查 Service Broker 端点配置,以确保这两个实例具有兼容的网络安全设置。如果一个实例的 Service Broker 端点指定 REQUIRED 或 ENABLED,则另一个实例的 Service Broker 端点不能指定 NONE。

请检查 Service Broker 传输安全模式的证书、用户和权限。有关详细信息,请参阅 Service Broker 传输安全性