路由和消息传递故障排除
本节提供了解决与路由和消息传递相关的常见问题的建议。
技术:诊断消息传递
如果消息在两个服务间不能成功传递,可以使用 ssbdiagnose 实用工具生成会话的运行时报告。运行时报告将显示会话操作遇到的任何错误。如果遇到错误,ssbdiagnose 还会分析服务之间的配置并报告所发现的任何配置问题。有关详细信息,请参阅 ssbdiagnose 实用工具。
问题:消息留在传输队列中
确保在数据库中激活了 Service Broker 消息传递。sys.databases 的 is_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 传输安全性。