Exchange Server 2003 邮件路由

 

上一次修改主题: 2007-03-06

上一主题已讨论,对于要发送给非本地收件人的邮件,路由引擎必须提供高级排队引擎,并提供目标传输路径中的下一跃点主机的有关信息以及下一跃点类型。下一跃点主机是实际的路由地址,下一跃点类型决定了高级排队引擎如何处理邮件。要提供这一重要信息,路由引擎必须全面了解整个路由拓扑。其中包括所有路由组及其服务器、路由组连接器,以及连接到外部邮件系统的连接器。可在 Exchange Server 2003 的 Active Directory 目录服务中获取此信息。

邮件路由和链路状态表

每一台 Exchange 2003 服务器都基于 Active Directory 和链路状态信息在内存中动态维护其自身的路由表,也称为链路状态表,具体如下所述:

  • 与路由有关的 Active Directory 信息 此信息存储在组织对象、路由组对象、连接器对象和服务器对象的属性中。这些对象驻留在配置目录分区中,并定义整个 Exchange 组织的路由拓扑。

    note注意:
    管理组不是 Exchange 组织中的路由拓扑的一部分。
  • 链路状态信息 该信息指定路由拓扑中的每个连接器可用 (up) 还是不可用 (down)。链路状态信息是动态的,当连接器遇到传输问题或者传输问题解决时,此信息可能会发生变化。有关链路状态更改和跨 Exchange 组织传播链路状态信息的详细信息,请参阅链路状态传播

初始化链路状态表

启动时,每一台 Exchange 服务器都用 Active Directory 中的下列信息初始化它的链路状态表:

  • 组织对象 路由拓扑边界是 Exchange 组织。也就是说,链路状态表不包含有关外部桥头服务器或外部邮件系统中的邮件连接器的任何信息。考虑到路由引擎,路由拓扑将终止在外部邮件系统连接器。因此,路由引擎读取在 Active Directory 中的 Exchange 组织对象的 objectGUID 属性中注册的 GUID,并用此 GUID 标记此链路状态表,以确定该路由信息所属的组织。
  • 路由组对象 路由引擎枚举任何管理组中存在的所有路由组,并在每个路由组中查询所有对象属性,其中包括列出所有路由组成员服务器的 msExchRoutingGroupMembersBL 属性。路由引擎将此信息放在链路状态表中。路由引擎还将服务器及服务器所属路由组的 GUID 放入内存中的服务器缓存中。服务器缓存中的每个条目都依次由服务器的 FQDN 及服务器所属路由组的 GUID 组成。
    另一个重要的路由组属性是 msExchRoutingMasterDN 属性,该属性指向所选路由组中的路由组主服务器的可分辨名称。有关路由组主服务器的任务和职责的详细信息,请参阅此部分后面的讨论。
  • 邮件连接器对象 路由引擎枚举每个路由组的“连接”容器中存在的所有对象类型为 msExchconnector 的子对象。“连接”容器中的 msExchconnector 对象是路由组中配置的路由组连接器和外部邮件系统连接器。路由引擎从这些连接器对象中读取所有属性,以确定地址空间、开销值、限制等等。路由引擎将每个连接器的信息放入链路状态表中。这使得邮件可以被路由到本地路由组外部的目标。

此过程将一直持续到路由引擎找到了所有直接和非直接连接的路由组,并查询到了其邮件连接器的详细配置信息。在此过程结束时,路由引擎便全面了解了整个 Exchange 组织中的所有可用传输路径。一个假定前提是所有链路都处于 up 状态,并且可用于邮件传输。链路状态表初始化完成后,路由引擎与本地服务器上的 Microsoft Exchange Routing Engine 服务通信,以获取反映每个连接器当前状态的动态链路状态信息。Exchange Routing Engine 服务通过 TCP 端口 691 连接到本地路由组中的路由组主服务器,以检索此信息。有关链路状态信息的详细信息,请参阅本主题后面的“分析链路状态表”部分。

路由引擎和 Exchange Routing Engine 服务

传输子系统中的路由引擎与 Exchange Routing Engine 服务具有不同的角色。Exchange Routing Engine 服务不执行任何邮件路由。Exchange Routing Engine 服务在本地路由组中的 Exchange 2000 Server 及 Exchange Server 2003 服务器之间传递链路状态信息。Exchange Routing Engine 服务是在 resvc.dll 中实现的,后者位于 \Program Files\Exchsrvr\bin\ 目录中。服务名为 RESvc。有关 Exchange Server 2003 的 Microsoft Windows 服务的详细信息,请参阅 Exchange Server 2003 服务依存关系

Exchange Routing Engine 服务是路由组内部的链路状态通信服务,而不是路由引擎。SMTP 高级排队引擎和 Exchange MTA 用来路由邮件的实际路由引擎是在名为 reapi.dll 的文件中实现的。对于 Exchange MTA,另外还在 mtaroute.dll 中提供了一些代码。因此,当 Exchange Routing Engine 服务停止时,高级排队引擎和 Exchange MTA 仍然使用 reapi.dll 中的代码来路由邮件。只是,此时不会再收到链路状态表的动态更新。

note注意:
尽管通常不推荐这样做,但是可以禁用组织中运行 Exchange Server 2003 的所有服务器的 Exchange Routing Engine 服务。此时,reapi.dll 中的代码仍然能够使用 Active Directory 中的信息来初始化每一台服务器上的链路状态表,但不会动态更新链路状态表。在这种情况下,Exchange Server 2003 执行静态邮件路由。

分析链路状态表

链路状态表是未存储在磁盘中的小型内存数据库。若要检查路由引擎用来制定路由决策的条目,可以使用 Exchange Server 2003 WinRoute 工具 (Winroute.exe),可以从 Downloads for Exchange Server 2003 网站下载该工具。

note注意:
还随 Exchange 2000 Server 一起提供 WinRoute 工具,但是最好下载 Exchange Server 2003 版的 WinRoute 工具,并在组织中的所有 Exchange 2000 及 Exchange Server 2003 服务器上使用此版本的工具。

WinRoute 工具连接到选定的 Exchange 服务器上的链路状态端口(TCP 端口 691),并提取链路状态表。该表中的信息是一系列 GUID 和 ASCII 文本,这些 GUID 和 ASCII 文本表示路由组、路由组成员以及路由组中的连接器。链路状态表还包含每个连接器的配置的有关信息。链路状态表中的信息字段以括号进行分隔,如下所示:

'General Info' ('Routing Group' 'Routing Group Master' 'Version Info' 'Routing Group Addresses' (Routing Group Members) (Connectors in Routing Group (Connector configuration))).

下面是链路状态表的一个简化示例(保留了一个路由组,其他所有路由组均被删除):

d38082e7c9ecd74dbff32bada8932642 d037d6eaf2fa7cd10934aca433390623 (489416bfa3a4ff459b8f4403f20cad0d 1650c1fe32aef740be236e1089e0da6a 8 0 2 c2da71f9b39ec748aaf44119a2bdcb36 {26}*.489416BF-A3A4-FF45-9B8F-4403F20CAD0D {4c}c=DE;a= ;p=TailspinToys;o=Exchange;cn=489416BF-A3A4-FF45-9B8F-4403F20CAD0D;* {55}/o=TailspinToys/ou=First administrative Group/*/489416BF-A3A4-FF45-9B8F-4403F20CAD0D ( 1650c1fe32aef740be236e1089e0da6a YES 1 1b20 {10}0701000000000101 ) ( aa582d35e9621c4ca8ae57aa33d953a1 ( CONFIG {4}SMTP {} {23}_aa582d35e9621c4ca8ae57aa33d953a1_D {63}/o=TailspinToys/ou=First administrative Group/cn=Configuration/cn=Connections/cn=RGC RG A <-> RG B 0 0 0 0 ffffffff ffffffff 0 1 0 () 0 () 0 () 0 () ARROWS ( {2}RG {20}83bd0e29fad06d4eb8b00faab3265cd5 1 {4}X400 {23}c=DE;a= ;p=TailspinToys;o=Exchange; 1 ) BH () TARGBH ( 766a192b43bfc3459ee85608d65a98a9 CONN_AVAIL {19}server01.TailspinToys.com ) STATE UP)))

(... next routing group... (... next routing members...) (... connectors in routing group (... connector configuration..)))

下表将此信息与链路状态表中的各个信息字段对照起来进行分析。

链路状态表中的信息

字段 注释

组织 objectGUID

d38082e7c9ecd74dbff32bada8932642

在 Active Directory 中的 Exchange 组织对象的 objectGUID 属性中注册的 GUID。

MD5 摘要

d037d6eaf2fa7cd10934aca433390623

MD5 摘要或哈希值。这是表示链路状态表版本号的加密签名。路由引擎可以根据此信息来确定它们是否具有相同的链路状态信息。如果信息不同,路由引擎将交换 OrgInfo 数据包,以确定哪一台服务器拥有最新的信息。OrgInfo 数据包中包含链路状态表,其中有路由拓扑的所有详细信息和状态。链路状态信息的传播在此部分的后面讨论。

路由组 objectGUID

489416bfa3a4ff459b8f4403f20cad0d

在路由信息所属的路由组对象的 objectGUID 属性中注册的 GUID。此 GUID 在链路状态表中位于 MD5 摘要的后面。

路由组主服务器 objectGUID

1650c1fe32aef740be236e1089e0da6a

在该路由组中的路由组主服务器的 objectGUID 属性中注册的 GUID。

每个路由组内部的路由组主服务器都负责维护链路状态信息,并将该信息传递给所有路由组成员。每个路由组中都只能有一个路由组主服务器存在。有关路由组主服务器的角色的详细信息,请参阅此部分后面的讨论。

版本信息

8 0 2 c2da71f9b39ec748aaf44119a2bdcb36

版本 8 0 2 分别是链路状态信息的主版本、次版本和用户版本。路由引擎使用此版本信息对链路状态信息的更新进行分类,如下所述:

  • 主要更新 表示路由拓扑的变化,例如,连接器配置的变化(也就是,添加或删除连接器、添加或删除连接器上的地址空间,或者将新的服务器指定为路由组主服务器)。
  • 次要更新 表示虚拟服务器或连接器可用性的变化。例如,如果连接器的源桥头服务器不可用,连接器的状态可能从 up 变为 down。
  • 用户更新 表示当 Exchange 服务器上的服务启动或停止时,或者当服务器断开与路由组主服务器的连接时所发生的变化。在路由组中添加新服务器也表示用户更新。

余下的数据是该版本信息的 GUID。

路由组地址

{26}*.489416BF-A3A4-FF45-9B8F-4403F20CAD0D {4c}c=DE;a= ;p=TailspinToys;o=Exchange;cn=489416BF-A3A4-FF45-9B8F-4403F20CAD0D;* {55}/o=TailspinToys/ou=First administrative Group/*/489416BF-A3A4-FF45-9B8F-4403F20CAD0D

将 SMTP、X.400、X.500 和地址信息与各个路由组 GUID 对应。路由引擎使用此信息来生成内部服务器缓存,后者用于确定路由拓扑中每台服务器所属的路由组。服务器缓存是路由引擎的内部表。

例如,假定 SERVER01 位于名为“第一个路由组”的路由组中,并且 FQDN 为 SERVER01.TailspinToys.com。按照路由组地址的定义,路由引擎在服务器缓存中为 SERVER01 创建一个条目,如下所示:

SERVER01.TailspinToys.com.489416BF-A3A4-FF45-9B8F-4403F20CAD0D.

在路由事件过程中,如果高级排队引擎将该 FQDN 传递给路由引擎,路由引擎便会在服务器缓存中进行查找,以找到与 SERVER01.TailspinToys.com 对应的条目,并快速确定目标路由组。X.400 和 X.500 地址同理;只有地址信息复杂一些。

路由组成员

( 1650c1fe32aef740be236e1089e0da6a YES 1 1b20 {10}0701000000000101 )

列出属于该路由组的所有服务器,并标识其状态。但是,请注意,路由引擎在路由邮件的过程中不使用此信息。关于路由引擎使用服务器缓存这一点,在此部分前面已讨论。

为便于系统监视,路由组成员在 Routing Group Members () 列表中列出。在 Exchange 系统管理器中依次打开“工具”节点、“监视和状态”和“状态”后,可以查看此信息。

Routing Group Members () 列表中的服务器状态条目包含下列信息:

  • 服务器的 objectGUID:1650c1fe32aef740be236e1089e0da6a
  • 该成员是否连接到路由组主服务器。“是”表示该服务器已连接。
  • 服务器版本号: 1
  • 内部版本号:1b20(十六进制)= 6944
  • 用户数据: {10}0701000000000101

用户数据表示服务器的状态。如果该值以 0701 开头,说明服务器可用,并且正在工作。如果该值以 0702 开头,说明服务器处于警告状态。如果该值以 0703 开头,说明服务器处于紧急状态。

要临时取消对服务器的监视,可以将服务器切换到维护模式。这时该值以 0781 开头。

路由组中的连接器

( aa582d35e9621c4ca8ae57aa33d953a1 ( CONFIG ))

从下一个左括号开始,属于该路由组的每个连接器都在单独的条目中列出。该条目包含连接器的 objectGUID 以及路由引擎用来制定邮件路由决策的配置信息。

note注意:
链路状态表中的连接器配置信息具有以下表条目中描述的字段。

连接器 objectGUID

aa582d35e9621c4ca8ae57aa33d953a1

在 Exchange 组织中唯一标识连接器的 GUID。

连接器类型

{4}SMTP

该字段出现在 CONFIG 关键字后,用于标识连接器类型。类型可以是 SMTP、X.400、Notes 或 Exchange Development Kit (EDK)。Notes 和 EDK 类型指的是连接到非 Exchange 邮件系统且基于 MAPI 的邮件连接器的实例。有关基于 MAPI 的连接器的详细信息,请参阅网关邮件连接器体系结构

tip提示:
大括号中的数字不是标识符。该数字指的是十六进制格式的字段值的字符串长度。
note注意:
路由组连接器没有明确的类型。路由组连接器使用 SMTP 传输邮件。

源桥头地址

{}

该字段可以有如下三种值之一:

  • 无值 如果未指定源桥头服务器,那么本地路由组中的任何服务器都可以使用该连接器来传输邮件。这适用于使用了“任何本地服务器都可以通过此连接器发送邮件”选项的路由组连接器。
  • 连接器 GUID 对于 SMTP 连接器和路由组连接器,可以指定特定的本地桥头服务器。在这种情况下,“源桥头地址”字段列出后接“_S”(不包括引号)的连接器 GUID,以指示这是源桥头,如:
    {23}_76290a25817c0643a1a6999e669b1d5f_S
    之后,本地桥头服务器会在连接器信息的 BH 字段中列出。
  • 桥头地址 X.400 连接器和基于 MAPI 的连接器不能有多个本地桥头服务器。对于这些连接器,在“源桥头地址”字段中指定本地桥头服务器,如:{8}SERVER01。为了提供可用性信息,之后本地桥头服务器还可能在连接器信息的 BH 字段中列出。

目标桥头地址

{23}_aa582d35e9621c4ca8ae57aa33d953a1_D

与“源桥头地址”字段一样,该字段可以有如下三种值之一:

  • 无值 X.400 连接器和基于 MAPI 的连接器在链路状态表中没有目标桥头服务器。这些连接器使用连接器特有的信息来确定其目标系统,如 X.400 连接器堆栈配置中的远程主机名。
  • 连接器 GUID 对于路由组连接器,“目标桥头地址”字段列出后接“_D”(不包括引号)的连接器 GUID,以指示这是目标桥头。在这种情况下,目标桥头服务器之后会在连接器信息的 TARGBH 字段中列出。
  • 桥头地址 当 SMTP 连接器用于相互连接路由组时,不能有多个目标主机。连接器配置要求指定远程路由组中的智能主机,该智能主机之后会被指示为目标桥头,如: {8}SERVER02.

旧的可分辨名称

{63}/o=TailspinToys/ou=First administrative Group/cn=Configuration/cn=Connections/cn=RGC RG A <-> RG B

这是采用旧的 Exchange 5.5 目录格式的连接器可分辨名称。该值对应 Active Directory 中的连接器对象的 legacyExchangeDN 属性。

日程安排 ID

0

“日程安排 ID”字段未使用,并始终设置为 0。高级排队引擎和 Exchange MTA 查询 Active Directory,以确定连接器的激活日程安排。

限制

0 0 0 ffffffff ffffffff 0 1 0 () 0 () 0 () 0 ()

“限制”字段标识连接器的作用域、邮件大小限制以及其他约束条件,如下所述:

  • 连接器的作用域由第一个数字标识。0 值表示作用域是“组织”。1 值表示作用域是“路由组”。
note注意:
路由组连接器的作用域始终为“组织”。可以限制外部邮件系统连接器仅仅在本地路由组中使用。
  • 下一个数字指示是否配置了触发传递。0 值表示无触发传递。1 值表示远程主机必须触发邮件传输(如 TURN/ETRN)。
  • 第三个数字标识允许通过此连接器的邮件类型(高、正常、低、系统和非系统)。
  • 接下来的八个字节指定邮件大小限制(如果有)。如果未对该连接器应用邮件大小限制,该值将为 ffffffff。
  • 第二个八个字节块指示是否设置了大邮件阈值。ffffffff 值表示未设置邮件阈值。其他任何值表示实际设置的阈值 (KB)。
  • 接下来的数字指定是否允许使用公用文件夹引用(0 = 允许,1 = 不允许)。
  • 再接下来的数字指示默认情况下是否接受来自每个人的邮件。1 值表示默认情况下接受所有邮件。0 值表示默认情况下拒绝所有邮件。
  • 接下来的四个字段 (0 () 0 () 0 () 0 ()) 是被允许或被拒绝通过此连接器发送邮件的原始发件人列表和通讯组列表。第一个列表包含被允许的原始发件人的可分辨名称,第二个列表包含被拒绝的原始发件人的可分辨名称,最后两个列表包含被允许的通讯组或被拒绝的通讯组。括号前面的数字表示每个列表中的条目数。
    下面是包含两个原始发件人的列表示例(此格式适用于所有接受列表和拒绝列表): 2 ( {2d}CN=Ted Bremer,CN=Users,DC=TailspinToys,DC=com {30}CN=Administrator,CN=Users,DC=TailspinToys,DC=com ).

地址空间

ARROWS ( {2}RG {20}83bd0e29fad06d4eb8b00faab3265cd5 1 {4}X400 {23}c=DE;a= ;p=TailspinToys;o=Exchange; 1 )

每个连接器至少有一个关联的地址空间。通过将收件人地址与可用的地址空间信息进行比较,路由引擎使用该信息来确定特定邮件的可能连接器。

在链路状态表中,ARROWS () 列表包含属于该连接器的各个地址空间。每个地址空间条目都包含如下三条信息:

  • 地址空间类型 地址空间类型确定了下一个位置采用的地址空间信息格式。例如,X.400 地址空间要求地址空间信息采用有效的 X.400 格式。而 SMTP 地址空间则包含 SMTP 域名的各部分。路由组连接器的地址空间类型为 RG,这代表路由组 objectGUID。
  • 地址空间 地址空间指定地址模式,路由引擎用它来比较收件人地址,以识别邮件的目标。路由引擎在外部收件人与内部收件人之间使用地址空间的方式不同。
    对于外部收件人,目标是连接外部邮件系统的邮件连接器。高级排队引擎将外部地址信息传递到路由引擎,并由路由引擎选择与目标最为匹配的连接器。例如,如果 SMTP 连接器有 SMTP 地址空间:*.net,并且另一个 SMTP 连接器有 SMTP 地址空间:*,则路由引擎选择第一个 SMTP 连接器来处理在 .net 域中的所有收件人,并用第二个 SMTP 连接器来处理其余的所有 Internet 收件人。
    对于本地组织中的收件人,地址空间在收件人策略中定义(地址空间设置为“此 Exchange 组织负责处理传递到此地址的所有邮件”)。如果收件人的地址与本地组织的地址空间匹配,分类程序将根据收件人的 msExchHomeServerName 属性确定收件人的主服务器。分类程序用主服务器的 FQDN 标记收件人,并由高级排队引擎将该 FQDN 传递到路由引擎,以便将邮件传递到位于本地组织中的目标。路由引擎使用 FQDN 来找到其服务器缓存。它查找与主服务器对应的条目,因为该条目中包含收件人的主路由组 GUID。
    路由引擎使用收件人的主路由组 GUID 来确定必须如何传输邮件,如下所述:
    1. 如果主路由组 GUID 与本地路由组 GUID 相同,那么说明收件人位于本地路由组中。在这种情况下,必须使用 Exchange 服务器的默认虚拟 SMTP 服务器将邮件直接传输到收件人的主服务器。路由引擎将收件人主服务器的 FQDN 返回给高级排队引擎,以指示下一跃点主机。
      note注意:
      运行 Exchange Server 5.5 的服务器是一个例外。它通过 RPC 和 MTA 服务与本地路由组中的 Exchange 2003 通信,这已在此部分前面说明。
    2. 如果主服务器所在的路由组不是本地路由组,那么必须使用路由组连接器将邮件传输到目标。只有路由组地址空间包含目标组 GUID 的连接器才能够将邮件传输到该路由组。因此,路由引擎可以创建一个包含所有可能传输路径的拓扑视图,并首先列出 Exchange 组织中所有可能目标的起点和终点。根据收件人的路由组 GUID,路由引擎可以找到邮件在 Exchange 组织中的最终目标,并且可以将到达该目标的最短路径中的下一跃点返回给高级排队引擎。有关详细信息将在此部分的后面讲述。
  • 开销 开销值与地址空间关联,并决定了首先选择哪个连接器来传输邮件。该值可以在 1 到 100 之间。如果可以通过多个连接器到达同一个目标,将首选开销值最低的连接器。如果多个连接器具有相同的开销值,路由引擎将随机选择一个连接器,以提供简单形式的负载平衡。

源桥头

BH ()

BH 字段列出连接器的本地桥头服务器及其状态信息。桥头服务器是使用如下三条信息来标识的:

  • 桥头服务器 objectGUID 在连接器配置中被指定为本地桥头服务器的虚拟 SMTP 服务器的 GUID。
  • 桥头服务器状态 指示桥头服务器可用性的信息,如下所示:
    • CONN_AVAIL 桥头服务器可用。
    • VS_NOT_STARTED 虚拟 SMTP 服务器已停止或未启动。
    • CONN_NOT_AVAIL 无法在桥头服务器上建立连接。例如,源桥头服务器无法建立与目标桥头服务器的连接。
  • 虚拟服务器 FQDN 充当该连接器的桥头服务器的虚拟服务器的 FQDN。

目标桥头

TARGBH ( 766a192b43bfc3459ee85608d65a98a9 CONN_AVAIL {19}server01.TailspinToys.com )

与 BH () 列表类似,TARGBH () 列表包含连接器的目标桥头服务器。此列表对于路由组连接器尤为重要。路由组连接器可以有多个远程桥头服务器。

在本例中,下列信息标识远程桥头服务器:

  • 桥头服务器 objectGUID 766a192b43bfc3459ee85608d65a98a9
  • 桥头服务器状态 CONN_AVAIL
  • 虚拟服务器 FQDN {19}server01.TailspinToys.com

状态

STATE UP

连接器的状态。该字段有两个可能的值:

  • STATE UP 表示连接器可用。
  • STATE DOWN 表示连接器不可用。

连接器状态是从连接器源桥头服务器的状态中得出的。只有在至少有一个源桥头服务器可用 (CONN_AVAIL) 时,连接器才处于 STATE UP 状态。如果连接器的所有源桥头虚拟服务器都未启动 (VS_NOT_STARTED),或者源桥头无法建立连接 (CONN_NOT_AVAIL),那么连接器状态将为 STATE DOWN。

note注意:
只有在连接器的所有本地桥头服务器都不可用时,该连接器才会被标记为 down。除了通过 DNS 路由的 SMTP 连接器和基于 MAPI 的连接器以外,配置为使用“任何本地服务器都可以通过此连接器发送邮件”选项的路由组连接器也从不标记为 down。其中有一个桥头服务器是 Exchange 5.5 服务器的路由组连接器从不标记为 down。
note注意:
如果 WinRoute 工具能够访问 Active Directory,便会将链路状态表中的 GUID 解析为采用可读格式的名称,从而提供了路由拓扑和链路状态表的直观视图。WinRoute 程序窗口的上窗格显示解析后的数据,中间窗格列出现有的所有地址空间,下窗格显示链路状态表中的原始信息。有关 WinRoute 工具的详细信息,请参阅 Tools for Exchange Server 2003中的工具下载信息。

Exchange 路由路径选择

在具有多个路由组的组织中,可能有多个路由路径的目标相同。通常,采用最高效(即最短或开销最低)的路由路径来传输邮件,而其他路由路径处于等待状态,以备在最佳路由路径暂时不可用时启用。例如,在如下图所示的拓扑中,所有路由组之间都存在多个传输路由路径。

b83a8987-67cd-4228-a68b-faf721d763d8

note注意:
邮件路由应遵循物理网络拓扑。如果在真正的中心辐射型结构中设计了基础网络拓扑(其中路由组 A 为中心组),那么定义如上图所示的路由组连接器没有意义。因而,由组 B、C、D 和 E 应当直接连接到路由组 A,并且所有路由组间的邮件传输都应当通过路由组 A 进行路由。在实际的中心辐射型布置中,没有备用的邮件路径,并且路由路径选择是很简单的。但是,为方便此部分进行说明,假定物理网络拓扑是网状结构,它采用如图所示的路由组连接器布置。

路由引擎使用下列信息来确定最佳路由:

  • 地址空间 配置路由组连接器时,可以使用连接器属性中的“连接的路由组”选项卡将可能的目标与邮件连接器关联。但是,路由组连接器不提供该选项卡。由于此连接器仅用于连接到路由组,因此路由引擎可以通过连接器配置来确定路由组地址空间。
    db861687-48f0-40cf-9e55-4fb6e7224d49
    可以通过“地址空间”选项卡将地址空间添加到连接器中。“链路状态表中的信息”中已提到,地址空间由地址类型(如 RG、SMTP、X400、MSMAIL 或 CCMAIL)、地址和开销值组成。分配给地址空间的开销值是一个重要的路由标准。路由引擎使用 Dijkstra 最短路径算法来制定路由决策。此算法就是基于开销值。

  • 连接器作用域 外部邮件系统连接器的作用域可能仅限于连接器的路由组,在这种情况下,只允许连接器本地路由组中的用户使用该连接器。默认情况下,所有连接器的作用域都是“整个组织”。

    note注意:
    路由组连接器始终可以用在整个组织中。
  • 限制 路由引擎确定邮件大小、优先级以及邮件类型(也就是系统邮件还是非系统邮件)。路由引擎将这些属性与可用的连接器限制信息进行比较。然后,它将由于违反连接器限制而无法传输邮件的那些连接器从可能的连接器列表中删除。

  • 状态 在选择路由的过程中只能选择可用的连接器。每个连接器的状态字段都指示该连接器可用 (STATE UP) 还是不可用 (STATE DOWN)。

路由路径选择过程

为了选择到达目标的最佳路径,路由引擎使用 Dijkstra 最短路径算法,计算在 Exchange 组织中从源路由组到目标路由组的最短传输路径。然后,路由引擎确定高级排队引擎应当用来传输邮件的最短路径中的下一跃点。

选择路由路径的过程由两步组成:

  1. 高级排队引擎调用路由引擎的 IMessageRouter 接口上的 GetMessageType 方法。在 GetMessageType 方法中,高级排队引擎将邮件以 MailMsg 对象的形式传递给路由引擎。
    在这一步中,路由引擎执行下列过程:
    1. 检查邮件跟踪信息以检测是否存在循环。如果检测到邮件循环,便会将邮件随同 NDR 一起返还给发件人。

    2. 读取或重新计算(如有必要)当前组织拓扑,也就是说,确定到达路由拓扑中的所有目标的最短路径列表(从本地路由组开始)。

    3. 在链路状态表中检查关于连接器的限制信息,并在必要时刷新此限制信息。

    4. 确定组织拓扑中可用来将邮件传输到目标的所有连接器,然后分析邮件特征和连接器限制,以排除不得用来传输邮件的所有连接器。

    5. 计算邮件的筛选值,该值唯一地定义邮件类型。邮件类型标识具有类似特征的邮件可以使用的实际路径。邮件类型会缓存起来。这样,路由引擎便不必为具有类似特征的后续邮件重新计算筛选值。

      note注意:
      高级排队引擎为每一种邮件类型都维护一个单独的邮件队列。
    6. 创建关联的邮件类型。关联的邮件类型与实际邮件类型类似,但却是使用较宽松的限制标准来计算的。如果由于连接器限制而使传输路径对于实际的邮件类型不可用,关联的邮件类型使 SMTP 传输子系统可以返回更多的错误代码。

    7. 将缓存的邮件类型的索引返回给高级排队引擎。

  2. 路由引擎确定最短路径中的下一跃点。为完成此步骤,高级排队引擎调用 IMessageRouter 接口上的 GetMessageType 方法。高级排队引擎此时传递给路由引擎的最重要信息是目标地址和邮件类型 ID。对于 Exchange 组织中的收件人,目标地址是收件人主服务器的 FQDN。路由引擎根据服务器缓存确定目标路由组、检查可用于该邮件类型的传输路径,并将到达目标路由组的传输路径中的下一跃点返回给高级排队引擎。然后,高级排队引擎可以将邮件传输到目标路径中的下一跃点。

Dijkstra 最短路径算法

要制定正确的路由决策,路由引擎必须了解到达路由拓扑中所有可能目标的最短路径。在复杂的路由拓扑中,路由引擎必须从到达所有目标的所有可用传输路径中选择最短的传输路径。此问题称为单源最短路径问题。

下图显示:即使在相对简单的路由拓扑中,从一个路由组到其他任何路由组之间也可能存在许多路由路径。该图以简化的形式显示图 5.4 中的路由组连接器,并假定其默认开销值为 1。

0bdc24c5-23dc-4590-b888-f551d15521ad

1959 年,Edsger Dijkstra 教授提出了一种算法,通过一次计算找到从指定源到拓扑中所有点的最短路径,从而解决了单源最短路径问题。

路由引擎采用 Dijkstra 算法,具体如下所述:

  1. 用路由拓扑来表示从一个路由组到其他所有路由组的所有路径,并假定路由拓扑是一棵生成树。这决定了拓扑必须包含所有路由组和路由组连接器,并且路由组之间不存在循环。因此,路由拓扑中允许邮件返回源路由组的路径是非法传输路径,在计算时不包括这些路径。
  2. 根据 Dijkstra 的算法,路由引擎维护两个路由组集合。第一个集合包含到源路由组的最短路径已被确定的所有组。第二个集合包含余下的所有路由组。起初,到源路由组的最短路径已被确定的路由组集合是空的。只要还有剩余的路由组未处理,路由引擎便会执行步骤 3 到步骤 6,如下所述:
  3. 路由引擎依据与源路由组的距离的当前最佳估计值(即开销值之和)对余下的路由组进行排序。
  4. 然后,将距离最近的路由组添加到被确定为具有最短路径的路由组集合中。
  5. 然后,路由引擎更新连接到该路由组的所有路由组的开销(如果这能够改善余下的每个路由组的最短路径最佳估计值),方法是将这些路由组之间的连接器的开销值加到距离值中。
  6. 更新所有已更新的路由组的前置路由组。前置路由组列表最终定义了从每个路由组到目标路由组的最短路径。

下列步骤说明了路由引擎如何找到从路由组 A 到路由拓扑中的其他所有路由组的最短路径。

  1. 计算开始于路由组 A,因为在此示例中源为路由组 A。路由组 A 到它本身的距离值是零。其他所有路由组的距离值尚未确定。
  2. 路由组 A 被添加到已确定到源路由组的最短路径的路由组集合中。然后,用与路由组 A 相邻的所有路由组的连接器开销值更新其距离值。然后所有这些路由组的原有值(用黑色箭头的源指示)都更新。前置路由组是路由组 A。
  3. 路由引擎依据与源路由组的距离的当前最佳估计值对余下的路由组进行排序。将距离最近的路由组添加到其最短路径已被确定的路由组集合中。由于路由组 B 和 C 具有相同的距离值,因此路由引擎随机选择一个路由组。本示例假定路由引擎选择路由组 B。
  4. 路由引擎计算与路由组 B 相邻的余下所有路由组的距离值,方法是:将路由组 B 与相邻路由组之间的连接器开销值与路由组 B 的距离值相加。只有在计算出的距离值小于已分配给该路由组的值时,才更新相邻路由组的距离值,并在之后更新前置路由组(用黑色箭头指示)。
    与路由组 B 相邻的路由组是路由组 C、D 和 E。路由组 C 和 D 的当前距离值未指定。因此,通过将其连接器的开销值与路由组 B 的距离值相加 (1+1) 来确定其距离值。然后所有这些路由组的前置路由组(用黑色箭头的源指示)都更新。前置路由组是路由组 B。
    路由组 C 未更新,因为路由组 C 的距离值与连接器开销之和 (1+1) 大于路由组 C 当前的距离值。
  5. 路由引擎依据与源路由组的距离的当前最佳估计值对余下的路由组进行排序,并将最近的路由组添加其最短路径已被确定的路由组集合中。该算法现在采用路由组 C,因为该路由组具有最小的距离值。
  6. 路由引擎计算与路由组 C 相邻的余下所有路由组的距离值,方法是:将路由组 C 与相邻路由组之间的连接器开销值与路由组 C 的距离值相加。只有在计算出的距离值小于已分配给该路由组的值时,才更新相邻路由组的距离值,并在之后更新前置路由组(用黑色箭头指示)。
    与路由组 C 相邻的余下路由组是路由组 D 和 E(路由组 A 和 B 已处理)。
    路由组 D 和 E 的当前距离值是 2。该值小于连接器开销与路由组 C 的距离值之和 (1+2)。因此,路由组 D 和 E 的距离值和前置路由组列表不更新。
  7. 路由引擎依据与源路由组的距离的当前最佳估计值对余下的路由组(路由组 D 和 E)进行排序,并将最近的路由组添加到其最短路径已被确定的路由组集合中。
    由于路由组 D 和 E 具有相同的距离值,因此路由引擎随机选择一个路由组。本示例假定路由引擎选择路由组 D。
    余下的唯一一个相邻路由组是路由组 E,该路由组的当前距离值为 2。该值小于连接器开销与路由组 D 的距离值之和 (1+2)。因此,路由组 E 的距离值和前置路由组列表不更新。
    尚未添加到其最短路径已被确定的路由组列表中的最后一个路由组是路由组 E。余下没有相邻的路由组。因此,最短路径的计算完成。从路由组 A 到拓扑中的其他所有路由组的最短路径都已确定。

邮件传输负载平衡

如前面步骤所述,如果存在多个开销值相同的路径,路由引擎将随机选择一条传输路径。但是,路由引擎不执行负载平衡。前面已指出,路由引擎缓存邮件类型信息,该信息指示邮件可用来到达目标的最短路径。因此,同一类型的所有邮件采用相同的路径,即便存在开销值相同的其他路径也是如此(例如,“路由组 A > 路由组 B > 路由组 E”和“路由组 A > 路由组 C > 路由组 E”)。

路由组之间的负载平衡

路由组之间真正的负载平衡只能通过使用一个具有多个桥头服务器的路由组连接器来实现。

下表列出了可以用在路由组之间的负载平衡配置。

路由组之间可能的配置

可能的配置 注释

具有多个源桥头服务器和/或多个目标桥头服务器的单路由组连接器。

使用这些类型的连接器,路由引擎可以将下一跃点信息中的连接器 GUID 返回给高级排队引擎。然后,高级排队引擎随机选择必须使用的桥头服务器,从而在所有桥头服务器之间平衡邮件传输负载。

如果邮件到达具有多个源桥头服务器的路由组连接器的某个源桥头服务器,邮件将不会被重新路由到其他任何源桥头服务器。在邮件到达路由组连接器后,便可直接传输到目标路由组。因此,其邮箱驻留在桥头服务器上的用户始终使用本地服务器将邮件传输到目标路由组。

note注意:
最好对两个路由组之间唯一的路由组连接器指定多个源桥头和目标桥头。这有助于改善负载平衡性能并提高冗余度。

具有相同的地址空间(或连接的路由组)、相同权重(开销)并且每个都有一个源桥头服务器和一个目标桥头服务器的多个连接器

在此类型的配置中,未实现真正的负载平衡。只有在一开始为给定邮件类型选择连接器时才会执行负载平衡。路由引擎仅确定邮件类型一次,并缓存此信息,之后将通过同一连接器路由该类型的所有邮件。第二个连接器只有在第一个连接器失败时才使用。但是,第二个服务器可能会选择第二个连接器,并以此方式使负载达到某种程度的平衡。

note注意:
在路由组之间使用多个连接器实例来实现负载平衡不是一种好方法,因为无法实现真正的负载平衡。

具有相同的地址空间(或连接的路由组)、不同权重(开销)并且每个都有一个源桥头服务器和一个目标桥头服务器的多个连接器

如果希望配置连接器使其自动进行故障转移,可以在不同的桥头服务器上创建两个单独的连接器,并使每个连接器的开销不同。连接器的链接状态是由其本地桥头服务器来确定的。如果开销最低的首选连接器上的桥头服务器不可用,将认为该连接器不可用,并且路由将自动选择第二个连接器。当开销最低的连接器所在的桥头服务器可用时,Exchange 服务器将再次开始使用它。

连接器与外部系统之间的负载平衡

取决于具体方案,可以有几种方式实现跨 SMTP 连接器的负载平衡。

  • 如果要在发送方组织中让跨越多个服务器的出站请求实现负载平衡,请配置多个源桥头。
  • 如果要让跨越多个目标服务器的通信实现负载平衡,则可以让目标管理员正确配置 DNS(使用合适的 MX 和 A 记录配置),也可以在连接器上指定多个智能主机地址。

或者,如果要确保故障转移弹性,请创建多个 SMTP 连接器,并将相同的地址空间、不同的开销和不同的源桥头作为作用域。如果开销最低的首选连接器上的桥头服务器不可用,将认为该连接器不可用,路由将自动选择第二个连接器。如果使用两个具有相同开销的连接器,则 Exchange 服务器随机选择要使用的桥头服务器和连接器。然后,如果此桥头服务器变得不可用,它们会将故障转移到第二个连接器。但是,在第一台桥头服务器变为可用时,服务器不会将故障回复到这台服务器上,因为其路由开销与它们正在使用的服务器的开销相同。

例如,由于地址空间不匹配,下图中的连接器配置不是针对故障转移的负载平衡配置。发送到 .Net 域中的外部用户的邮件始终通过地址空间为 .Net 的 SMTP 连接器传输。这是因为路由引擎在评估开销之前,先选择最具体的地址。

7de23cb6-9bd9-43b1-b725-90ce114b2c4e

note注意:
如果地址空间为 *.Net 的连接器上存在限制,并且这些限制使得某些邮件无法通过该连接器(例如,由于拒绝发件人通过该连接器传输邮件),那么路由引擎会将邮件随同 NDR 一起返还给发件人。路由引擎不会重新尝试通过第二个连接器来传输这些邮件。将使用地址空间最具体的连接器来传输邮件。计算传输路径的过程中,不会考虑地址空间具体程度较低的连接器。

基于链路状态信息的邮件重新路由

如果连接器无法传输邮件,高级排队引擎将通知路由引擎链路出现故障。这可能导致路由引擎将连接器标记为 down。在这种情况下,将重新路由所有排队的邮件。

如果满足下列条件之一,路由引擎便会认为连接器的状态为 down:

  • 路由引擎无法与连接器的任何源桥头服务器建立连接,并且在路由组主服务器与源桥头服务器之间没有与端口 691 的 TCP/IP 连接。在链路状态表中,不可用的源桥头服务器标记为 VS_NOT_STARTED。
  • 任何源桥头服务器都无法成功地将邮件传输到目标桥头服务器。无法将邮件传输到目标的源桥头服务器标记为 CONN_NOT_AVAIL。
note注意:
如果使用 X.400 连接器,但是该连接器无法传输邮件,则 xchange MTA 会通知路由引擎发生了链路故障。这时源桥头服务器的状态为 CONN_NOT_AVAIL。X.400 连接器只能有一个源桥头服务器。

邮件重新路由

为确保有效的邮件传输,路由引擎会在链路状态发生任何变化时立即通知高级排队引擎和 Exchange MTA。为避免通过已断开的路径发送邮件,必须再次路由所有排队的邮件。此过程称为重新路由。在重新路由过程中,高级排队引擎丢弃缓存的所有下一跃点信息,因为这些信息不再有效。当前等待传输的每一封邮件都再次被传递到路由引擎,由路由引擎重新计算下一跃点。这可能是一项非常耗费资源的任务。

下图显示了一个重新路由示例,在该示例中,路由组 E 中的桥头服务器的状态为 down。当前没有任何邮件能够到达该路由组。当路由引擎重新计算将邮件传输到路由组 E 中的收件人的最短路径时,发现没有可用的路径。路由过程中,不考虑标记为 down 的连接器。因此,路由组 E 当前处于孤立状态。

3e7b77fb-c3c7-47c4-8961-8a3ea10d7581

由于不存在有效路径,因此路由引擎无法为等待传输到路由组 E 的邮件确定有效的下一跃点。路由引擎通过下一跃点类型信息通知高级排队引擎下一跃点当前不可达。高级排队引擎必须保留邮件,直到至少有一个传输路径可用,或者直到邮件过期,而必须随同 NDR 一起返还给发件人。

note注意:
如果只有一个路由组连接器存在,而没有备用路径,那么链路状态将始终标记为可用,以减少路由拓扑中的链路状态变化次数。Exchange Server 2003 将邮件排队,并在传输路径再次可用时将其发送出去。

重新路由和地址空间

与负载平衡一样,Exchange Server 2003 只通过地址空间相同的连接器来重新路由邮件。例如,您可能在不同的桥头服务器上创建了两个独立的连接器,两个连接器地址空间相同但开销不同。如果首选连接器不可用,路由引擎将自动选择第二个连接器,直到主连接器再次可用。

note注意:
路由引擎不会将邮件从地址空间具体的连接器重新路由到地址空间不具体的连接器,因为路由引擎认为这是另一个目标。邮件将保留在源桥头服务器上,直到地址空间具体的连接器可用。

如果地址空间为 *.Net 的连接器上存在限制,并且这些限制使得某些邮件无法通过该连接器(例如,由于拒绝发件人通过该连接器传输邮件),那么路由引擎会将邮件随同 NDR 一起返还给发件人。路由引擎不会重新尝试通过第二个连接器来传输这些邮件。将使用地址空间最具体的连接器来传输邮件。计算传输路径的过程中,不会考虑地址空间具体程度较低的连接器。

连接器恢复

如果出现下列任一种情况,路由引擎可确定连接器再次可用:

  • VS_NOT_STARTED 路由组主服务器建立了与源桥头服务器上的 TCP 端口 691 的连接。源桥头服务器标记为 CONN_AVAIL,并且由于至少有一个源桥头服务器可用于该连接器而使连接器的状态切换为 STATE UP。
  • CONN_NOT_AVAIL 对于不可用的连接器,即使没有等待传输的邮件,桥头服务器也继续每隔 60 秒重试连接。连接建立后,高级排队引擎或 Exchange MTA 报告路由引擎从源桥头服务器建立出站连接成功。之后,路由引擎将源桥头服务器的状态切换为 CONN_AVAIL,而将连接器的状态切换为 STATE UP。

重新路由和激活日程安排

所有类型的连接器都允许您配置连接器日程安排,这样您可以在特定的时间传输电子邮件。可以将连接器配置为始终处于活动状态、在指定的时间处于活动状态,或者从不处于活动状态。在最后一种情况下,除非再次更改连接器日程安排,否则连接器将不会传输邮件。还可以将连接器配置为远程启动。这意味着连接器自己不启动连接,而是等待远程服务器连接到它并触发邮件传输。

连接器日程安排仅影响邮件传输,而不影响邮件路由。对于具有任何日程安排类型的连接器而言,只要其状态为 STATE UP,路由引擎就认为它可用。因此,邮件甚至可能路由到激活日程安排设置为“从不”的连接器。这些连接器的链路状态不会发生变化,并且不会重新路由邮件。邮件将在连接器队列中等待,直到激活日程安排被更改。远程启动的连接器也是如此。邮件在等待检索的过程中,不会被重新路由。

tip提示:
如果要避免邮件路由到连接器,应将其最大邮件大小设置为 1 KB。