同一实例上不同数据库上的相同服务代理服务名称

The same service broker service names on different databases on the same instance

我通过服务代理创建了 server1<-->server2 通信。我在两台服务器上都定义了路由并且运行良好。当我定义路线时,我使用了以下代码:

CREATE ROUTE [SB_Cms_TimesheetRoute]
WITH SERVICE_NAME = '//DB1/DB2/UpdatedJobAssignments_TargetService',
ADDRESS = 'tcp://$(DB1_SERVER):4022';

一切正常 - 没有抱怨。我唯一无法理解的是,我可以在 $(DB1_SERVER) 实例上的不同数据库上创建具有相同名称的服务。 Service Broker 如何理解要使用的实例?

Service Broker 将创建多个同名服务理解为横向扩展方案。 CREATE ROUTE 有一个可选的 BROKER_INSTANCE 参数,您省略了它,这对于处理同一服务的多个实例至关重要。 broker_instance 必须与目标 sys.databases 中的 service_broker_guid 值匹配。

假设您创建了两个服务,都命名为 '//UpdatedJobAssignments_TargetService'(您永远不应在服务名称中放置 DB1DB2)。一项服务在 DB1 中,它具有 service_broker_guid 值 8597e044-6057-423f-978c-096b0c4212b7,而另一项服务在 DB2 中,它具有 service_broker_guid 值 29acd670-77bb-47da-baf9-fc74b714c8dd。您将创建两条路线,每条路线一条:

CREATE ROUTE [SB_Cms_TimesheetRoute_DB1]
WITH SERVICE_NAME = '//UpdatedJobAssignments_TargetService',
BROKER_INSTANCE = '8597e044-6057-423f-978c-096b0c4212b7',
ADDRESS = 'tcp://$(DB1_SERVER):4022';

CREATE ROUTE [SB_Cms_TimesheetRoute_DB2]
WITH SERVICE_NAME = '//UpdatedJobAssignments_TargetService',
BROKER_INSTANCE = '29acd670-77bb-47da-baf9-fc74b714c8dd',
ADDRESS = 'tcp://$(DB2_SERVER):4022';

现在,当您开始针对 //UpdatedJobAssignments_TargetService 服务的新对话时,Service Broker 会将您的第一条消息路由到两个可能的目的地之一。在同一个对话框 上发送的所有后续消息 将确定性地选择相同的目的地。您可以稍后动态添加更多服务实例,只需声明一个具有正确 BROKER_INSTANCE 值的相应路由即可。

您还可以通过在 BEGIN DIALOG 语句中指定所需的代理实例来显式定位所需的服务实例:

BEGIN DIALOG CONVERSATION @h 
FROM ...
TO '//UpdatedJobAssignments_TargetService', '29acd670-77bb-47da-baf9-fc74b714c8dd'
ON CONTRACT ...
WITH ...;

此语法将使对话框确定性地以 DB2 中的服务为目标。 这是必需的,例如,当您知道处理对话所需的状态在 DB2 中时。