Service Broker 路由

本主题详细说明 Service Broker 如何路由消息。有关概述,请参阅 路由

对于大多数应用程序,可以使用一个简单的 Service Broker 路由方法。在包含服务的每个数据库中,为该服务与之通信的外部服务指定一个路由。同时,Service Broker 还提供一个复杂的路由系统,以处理应用程序需要更复杂行为时的情况。有关阐释路由处理过程的示例,请参阅 Service Broker 路由示例

路由处理过程说明

SQL Server 维护两种不同级别的路由信息。每个数据库都包含一个本地路由表 sys.routes,它用于从该数据库发起的会话。对于在 SQL Server 实例中发起的会话,SQL Server 会在创建此会话的数据库中搜索该路由表。对于从实例外部到达的会话,SQL Server 将搜索 msdb.sys.routes

无论会话是从实例内部还是从实例外部发起的,基本的匹配过程都是相同的。此过程忽略已过期的路由。路由处理过程由三个不同的步骤组成:

  1. 查找匹配的路由。Service Broker 通过匹配服务名称和 Service Broker 标识符来查找一组可能的路由。

  2. 选择路由。Service Broker 从这组可能的路由中选择其一。

  3. 定位目标服务。当选定的路由指定 'LOCAL' 作为网络地址时,Service Broker 在实例中查找服务。如果实例中不存在该服务,则 Service Broker 可能会返回步骤 2 并选择其他路由。

在消息从发起方发送到目标并且发起方收到来自目标的确认消息之后,发起方将使用确认消息中的 Service Broker 标识符将后继消息路由到同一目标。Service Broker 对确认消息进行处理;该过程对于使用 Service Broker 的应用程序是透明的。有关确认消息的详细信息,请参阅Service Broker 通信协议

来自目标服务的回复消息

如果从实例外部到达的消息来自目标服务,则 SQL Server 将检查当前实例是否包含消息中的 Service Broker 标识符。如果包含,则消息在当前实例中传递,如“定位目标服务”中所述。否则,SQL Server 将按照标准的匹配过程进行处理。

查找匹配的路由

下面的过程说明 SQL Server 如何匹配路由。在每一步,如果有一个或多个路由匹配,则结束匹配过程,然后 Service Broker 将按如下所述选择匹配的路由之一:

  1. 如果会话指定了 Service Broker 标识符,则查找服务名称和 Service Broker 标识符都完全匹配的路由。

  2. 查找未指定 Service Broker 标识符但服务名称完全匹配的路由。

  3. 如果会话没有指定 Service Broker 标识符,则在指定了 Service Broker 标识符的路由中查找服务名称完全匹配的路由。如果路由表包含多个具有匹配的服务名称但 Service Broker 标识符不同的路由,则将任意选择一个 Service Broker 标识符。然后,只匹配使用该 Service Broker 标识符的那些路由。

  4. 如果存在到动态路由服务的路由,而且没有挂起的对服务路由的请求,则将会话标记为 DELAYED 并向动态路由服务请求路由信息。

  5. 查找既没有指定服务名称也没有指定 Service Broker 标识符的路由。

  6. 如果会话指定了 Service Broker 标识符,并且实例包含的一个或多个数据库中含有与会话中指定的名称匹配的服务,则会路由该会话,就如同路由表包含一个具有该服务名称且网络地址为 'LOCAL' 的路由一样。

  7. 将会话标记为 DELAYED。

将会话标记为 DELAYED 时,Service Broker 会在超时期限过后再次执行匹配过程。请注意,未能找到匹配的路由不视为错误。

选择路由

如果匹配过程找到多个匹配的路由,则 Service Broker 将从中选择一个路由。为此,具有相同 Service Broker 标识符、服务名称和网络地址的路由被视为相同的路由。Service Broker 使用下面的过程选择具体的路由。在每个步骤中,如果没有路由匹配此步骤中列出的地址规范,则继续执行下一步。

  1. 从指定镜像地址的路由中选择一个。

  2. 从指定 'LOCAL' 作为网络地址的路由中选择一个。如果此 SQL Server 实例中不包含与会话中指定的名称相匹配的服务,则继续执行步骤 3。

  3. 从指定网络地址的路由中选择一个。

  4. 从指定 'TRANSPORT' 作为网络地址的路由中选择一个。

在 Broker 转发处于不活动状态时,如果会话不是在当前实例中发起的而且选定的路由地址不是 'LOCAL',则 Service Broker 将删除该消息。

定位目标服务

如上所述,当匹配的路由将 'LOCAL' 指定为网络地址时,Service Broker 将消息传递到当前实例中的服务。对于从实例外部发起的消息,路由必须存在于 msdb.sys.routes 中。对于从实例内部发起的消息,匹配的路由必须存在于启动该会话的数据库的 sys.routes 表中。

Service Broker 确定了消息所对应的服务在当前实例中之后,Service Broker 就必须在该实例中找出此服务。如果在会话或路由中存在会话的 Service Broker 标识符,则 Service Broker 将消息传递给由该 Service Broker 标识符标识的数据库。

否则,Service Broker 首先通过在包含此会话的数据库中搜索服务名称来查找相应的服务。然后,它搜索此实例中的其他数据库。Service Broker 会将消息传递给找到的第一个服务。但请注意,Service Broker 搜索实例中其他数据库的顺序是未指定的,因而不能保证在会话间是一致的。这意味着,如果实例中存在目标服务的多个副本,则 Service Broker 会随机选取一个服务作为目标。

其他注意事项

为了提高可靠性,Service Broker 路由包含避免出现路由循环的安全措施。Service Broker 路由支持数据库镜像,并且可以将会话透明地重定向到镜像数据库的活动方。

路由循环

Service Broker 消息转发跟踪消息转发的次数,以防止出现无限路由循环。有关详细信息,请参阅 Service Broker 消息转发

如果匹配的路由包含的网络地址解析为当前实例,则 SQL Server 将该会话视为从实例外部发起的会话。Service Broker 使用 msdb.sys.routes 中的路由来路由会话消息。这些消息的路由确定过程与来自实例外部的消息的路由确定过程相同。特别是,Service Broker 的消息转发必须处于活动状态,才能将消息转发到 'LOCAL' 以外的网络地址。

镜像地址

从初始匹配路由集中选择路由时,带有镜像地址的路由优先级最高。但是,在为会话查找匹配的路由时,Service Broker 不会对镜像地址予以特殊考虑。

如果 Service Broker 选择的路由指定了一个镜像地址,并且 Service Broker 以前没有使用该路由传递过消息,则 Service Broker 会向这两个地址都发送请求,以确定当前哪一实例为主实例。Service Broker 标识出主实例后,Service Broker 会将使用此路由的所有消息都发送到该主实例,而不再联系镜像实例。如果该主实例无法访问,或者该实例指示自己不再是主实例,并且在另一个地址上的 SQL Server 实例指示自己是新的主实例,则 Service Broker 会将消息发送到这一对镜像地址中的另一个地址。

在 Service Broker 无法访问主实例而镜像伙伴又没有声明自己成为新的主实例的情况下,Service Broker 不会将消息发送给镜像伙伴。Service Broker 将重试主实例地址和镜像伙伴地址,直到主实例可访问或镜像伙伴指示自己现在是主实例了。通过采用这种方法,Service Broker 可在主实例和镜像伙伴可以通信而发送消息的实例无法访问主实例的情况下可靠地传递消息。