如何在香港服务器用 Windows Failover Cluster 打一套 Exchange 高可用,顺手把跨区域邮件同步延迟也抹平

周二早上 9:17,我刚在机房门口把咖啡放下,深圳销售总监一个电话打进来:“昨晚给香港法务发报价单,邮件又晚了两分钟才到,客户那边直接问我们是不是系统老旧。”
我看了下监控:香港机房到新加坡机房 RTT 在 35–40ms 摆动,北京到香港偶发 120ms 峰值。我们原来那套单数据中心的 Exchange 就靠一台大机器抗,跨区域靠公共链路传。问题本质很清楚:没有原生的数据库级高可用(DAG)跨站部署、复制流量和业务流量抢同一条路、Failover Cluster 参数没按跨子网调优。
于是我干脆把这次优化落成一篇“可落地”的实操记录:在香港服务器上用 Windows Failover Cluster + Exchange DAG 做高可用,同时把跨区域(港↔新、港↔内地)复制的延迟打平。
目标与范围
业务目标
本地(香港)邮箱持续可用:单节点故障自动切换 ≤ 60 秒,无需人工介入。
跨区域复制稳定:港↔新复制端到端 RPO ≈ 0(日志级同步)、RTO ≤ 10 分钟(人工触发/自动化脚本触发)。
消化延迟:复制延迟常态 < 5 秒;在跨境链路波动时不丢日志、不炸队列。
技术目标
- Exchange 2019 DAG(无管理访问点)+ Windows Server 2022 Failover Cluster。
- DAG 三副本:HK-EX01(主)、HK-EX02(本地副本)、SG-EX01(跨站副本/或滞后副本)。
- 独立 FSW 见证(HK-FSW),并配置 AlternateWitnessServer 以便全站切换。
- 调优 Cluster 跨子网心跳、复制网络隔离、队列/日志参数、TCP 与 NIC。
- 持续监控与自动化演练。
现场硬件与网络
| 角色 | 型号/配置 | 存储 | 网卡 | 系统 |
|---|---|---|---|---|
| HK-EX01 / HK-EX02 | 2×Xeon Silver 4310、128GB RAM | 系统盘:RAID1 SATA SSD;DB+Log:2× U.2 NVMe(DB),1× SATA SSD(Log) | 2×10GbE(Intel X710),1×1GbE 管理 | Windows Server 2022 Datacenter + Exchange Server 2019 CU(近两季版本) |
| SG-EX01 | 同上(略降内存到 96GB) | 同上 | 同上 | 同上 |
| HK-FSW(见证) | 小型虚机 2 vCPU/4GB | 100GB 普通盘 | 1GbE | Windows Server 2022 Standard |
| 交换机 | Arista/Juniper 10GbE TOR | Jumbo 9000 开 | - | - |
| 链路 | HK↔SG 专线/MPLS + 互联网备份 | 基线 RTT 35–40ms | - | - |
IP 规划(重点只列业务相关)
| 网络 | 子网 | 用途 | 备注 |
|---|---|---|---|
| HK-MAPI | 10.10.10.0/24 | 客户端/MAPI/SMTP/HTTPS | 走 10GbE,和复制网络物理/逻辑隔离 |
| HK-REPL | 10.10.20.0/24 | DAG 复制 | 仅 DAG/Seed/SMB |
| SG-MAPI | 10.20.10.0/24 | 同上 | - |
| SG-REPL | 10.20.20.0/24 | 同上 | - |
| 管理网 | 172.16.1.0/24 | iDRAC/管理 | 不参与 DAG |
DNS/AD
- 单一林单一域(例如 corp.example.com),两站点:HK-Site 与 SG-Site,各一台可写 DC。
- 时间同步统一指向同一权威 NTP。
方案设计要点(为什么这么配)
DAG 无管理访问点(IP-less)
Exchange 2016/2019 推荐不再为 DAG 分配单独的 Cluster 名称和 IP,减少 DNS/ARP 带来的漂移问题。
复制网络隔离
MAPI 与复制网络走不同 VLAN/路由,避免峰值时互相拖累。
DAC(Datacenter Activation Coordination)
防止跨站“脑裂”——断站恢复时,必须人工(或自动化脚本)确认才能全站激活。
见证在主站(HK),备用见证在 SG
正常情况下提高本地可用性,跨站切换时可快速改挂备用见证。
Cluster 跨子网参数调优
默认心跳阈值适合同城;跨区域要提高阈值,避免短抖动就把节点踢出。
滞后副本(Lagged Copy)(可选)
在 SG 保留 12–24 小时滞后,防范逻辑删除/批量误删类事故。
前置检查清单(落地用)
AD 健康(dcdiag、repadmin /replsummary 无明显报错)。
每台 Exchange 节点 不是 DC。
所有节点时钟偏差 ≤ 2s。
防火墙开放:
- Cluster:UDP 3343(心跳)、TCP 3343(?后文按 WSFC 实际)、SMB 445(见证/Seeding)。
- Exchange 复制:TCP 64327(MSExchangeRepl),Seeding 走 445。
- 客户端/外部:25/443/587/110/995/143/993(按实际开启)。
NIC 驱动、固件一致;关闭省电;Jumbo 9000 全路径打通(含交换机)。
Edge/反垃圾与出入口策略不在 DAG 改造窗口内调整,避免定位复杂化。
部署步骤(一步不落)
1)安装角色与功能(所有 EX 节点)
# 以管理员 PowerShell
Install-WindowsFeature NET-Framework-45-Features, RSAT-ADDS, RSAT-Clustering, RSAT-Clustering-PowerShell, RSAT-Clustering-CmdInterface, Failover-Clustering, FS-FileServer -IncludeAllSubFeature -IncludeManagementTools
# 可选:启用 .NET 需要的 TLS/Schannel 优化(视企业基线)
安装 Exchange 前置(UCMA 等按版本官方先装),然后安装 Exchange Server 2019(邮箱角色)。安装完成后补丁到目标 CU 水平并重启。
2)创建 Windows Failover Cluster(由 Exchange DAG 驱动,无管理访问点)
提示:从 Exchange 2016 开始,不要自己手动 New-Cluster 来跑 Exchange 的资源;让 DAG 去创建和管理底层 Cluster。你只需要确保每台节点的 Failover Clustering 角色已装好。
3)准备见证服务器(HK-FSW)
加域,确保 Exchange Trusted Subsystem 对见证目录有 本地管理员 或至少 读/写。
预创建目录 C:\DAGWitness 并授予权限。
4)创建 DAG(在任一 EX 节点的 Exchange 管理 Shell)
# 无管理访问点的 DAG:不指定 IP 地址
New-DatabaseAvailabilityGroup -Name "DAG-HK-SG" `
-WitnessServer "HK-FSW.corp.example.com" `
-WitnessDirectory "C:\DAGWitness" `
-DatacenterActivationMode DagOnly `
-NetworkCompression InterSubnetOnly `
-NetworkEncryption InterSubnetOnly
InterSubnetOnly:同子网内不压/不加密,跨子网(港↔新)才压缩/加密,兼顾性能与安全。
添加成员:
Add-DatabaseAvailabilityGroupServer -Identity "DAG-HK-SG" -MailboxServer "HK-EX01"
Add-DatabaseAvailabilityGroupServer -Identity "DAG-HK-SG" -MailboxServer "HK-EX02"
Add-DatabaseAvailabilityGroupServer -Identity "DAG-HK-SG" -MailboxServer "SG-EX01"
确认状态:
Get-DatabaseAvailabilityGroup -Identity DAG-HK-SG -Status | fl Name,Servers,OperationalServers,WitnessServer
5)规划 DAG 网络:区分 MAPI 与 REPL
Exchange 默认会识别网络,但跨站/多 NIC 时建议显式核对:
Get-DatabaseAvailabilityGroupNetwork -Identity DAG-HK-SG | ft Name,Subnets,ReplicationEnabled
# 示例:把 REPL 网络(10.10.20.0/24 & 10.20.20.0/24)设为 ReplicationEnabled=$true, MAPI 网络设为 $false
Set-DatabaseAvailabilityGroupNetwork -Identity "DAG-HK-SG\DAGNetwork01" -ReplicationEnabled:$false # MAPI
Set-DatabaseAvailabilityGroupNetwork -Identity "DAG-HK-SG\DAGNetwork02" -ReplicationEnabled:$true # REPL
6)为每个数据库添加副本并 Seeding
# 举例:现有 DB 名为 DB01、DB02,主在 HK-EX01
Add-MailboxDatabaseCopy -Identity "DB01" -MailboxServer "HK-EX02"
Add-MailboxDatabaseCopy -Identity "DB01" -MailboxServer "SG-EX01" -SeedingPostponed
# 进行跨站 Seeding(用 REPL 网络,走 SMB 445)
Update-MailboxDatabaseCopy -Identity "DB01\SG-EX01" -CatalogOnly:$false
可选:SG 做滞后副本
Set-MailboxDatabaseCopy -Identity "DB01\SG-EX01" -ReplayLagTime 12:00:00 -TruncationLagTime 12:00:00
7)Cluster 跨子网心跳调优(非常关键)
跨站默认心跳门限偏紧,建议:
# 查看当前
(Get-Cluster).SameSubnetDelay
(Get-Cluster).SameSubnetThreshold
(Get-Cluster).CrossSubnetDelay
(Get-Cluster).CrossSubnetThreshold
# 调优:跨子网延时容忍提高
(Get-Cluster).CrossSubnetDelay = 2000 # 毫秒
(Get-Cluster).CrossSubnetThreshold = 10 # 次
# 同子网也可适度放宽(视稳定性)
(Get-Cluster).SameSubnetDelay = 1000
(Get-Cluster).SameSubnetThreshold = 10
这组参数在我们 HK↔SG 35–40ms 的链路上非常稳,短抖动不再误判节点下线。
8)NIC 与 TCP 调优(只做“正收益且可回滚”的)
# 开启/确认 RSS/NetDMA/自动窗口调优为默认或建议值
netsh int tcp show global
# 如需调整(谨慎,先单节点验证)
netsh int tcp set global autotuninglevel=normal
netsh int tcp set global rss=enabled
# Jumbo MTU(示例 9000):需网卡与交换机端到端一致
# PowerShell 修改 NIC(示例),名称按实际
Get-NetAdapterAdvancedProperty -Name "Ethernet 10G"
Set-NetAdapterAdvancedProperty -Name "Ethernet 10G" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"
经验:不要一上来就疯狂关 LSO/Checksum Offload。新一代 10GbE 驱动配合现代栈通常开着更稳。仅在明确定位到 NIC Offload Bug 时再关。
9)配置备用见证(跨站切换预案)
Set-DatabaseAvailabilityGroup -Identity DAG-HK-SG `
-AlternateWitnessServer "SG-FSW.corp.example.com" `
-AlternateWitnessDirectory "C:\DAGWitness"
10)健康检查与演练
# 复制健康
Test-ReplicationHealth -Identity HK-EX01
Get-MailboxDatabaseCopyStatus * | ft Name,Status,CopyQueueLength,ReplayQueueLength,ContentIndexState
# 计划性切换(校验 RTO)
Move-ActiveMailboxDatabase -Identity DB01 -ActivateOnServer HK-EX02 -Confirm:$false
关键参数与端口表
| 项 | 值/建议 | 说明 |
|---|---|---|
| DAG 类型 | 无管理访问点 | Exchange 2016/2019 推荐 |
| NetworkCompression | InterSubnetOnly | 只在跨子网压缩 |
| NetworkEncryption | InterSubnetOnly | 只在跨子网加密 |
| CrossSubnetDelay | 2000 ms | 心跳包间隔 |
| CrossSubnetThreshold | 10 | 连续 10 次丢包才判离线 |
| ReplayLagTime | 12–24h(可选) | SG 滞后副本 |
| 复制端口 | TCP 64327 | MSExchangeRepl |
| 心跳端口 | UDP 3343 | WSFC |
| Seeding/见证 | SMB 445 | 文件复制/见证目录 |
| 监控脚本频率 | 1–5 分钟 | 见文末运维手册 |
我踩过的坑(以及怎么在机房里把它们填平)
CNO/对象权限
首次 New-DatabaseAvailabilityGroup 失败,提示无法在 AD 创建 Cluster 对象。原因是 OU 权限被收紧。解决:让 Exchange Trusted Subsystem 对应 OU 有创建计算机对象权限,或由 AD 管理员预创建 CNO 并给权限。
见证目录权限不完整
DAG 创建正常,但 Witness 不可用,日志报 Access Denied。现场核查后在 HK-FSW 上给 Exchange Trusted Subsystem 和 Exchange Servers 组 完全控制,目录继承打开。
Jumbo MTU 不成对
只在交换机开了 Jumbo,服务器 NIC 忘记改,导致复制间歇性重传。ping -f -l 8000 一测就暴露。修:端到端一致 9000/9014。
跨站防火墙策略遗漏 64327
Seeding 正常但复制卡住,CopyQueueLength 不下降。最后发现是 SG 侧边界防火墙没开放 64327。补规则即刻恢复。
DAC 未开启导致“脑裂”风险
演练时拔掉港站主路由,SG 自动激活,我们恢复链路后港站也想激活,好在提前回放演练发现,立刻统一启用 -DatacenterActivationMode DagOnly 并在切换 Runbook 加上 Set-DatabaseAvailabilityGroup -DatacenterActivationMode DagOnly 的校验步骤。
滞后副本忘了 Playdown
有次同事误删大量邮箱,想从滞后副本回滚,结果副本因为 ReplayLagTime 到点已经回放。后来我们把滞后副本的 TruncationLagTime 与回放策略写进 SOP,并用脚本在事故发生窗口内 冻结回放。
实测效果(两周观测窗口)
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 港↔新 复制延迟(P95) | 18.4 s | 3.2 s |
| 港站内切换 RTO(单 DB) | 3–5 分钟(人工) | < 60 s(自动) |
| 客户端投递 P95(港内) | 1.4 s | 0.9 s |
| 大附件上行占满对复制影响 | 严重(偶发 30s+) | 可控(<5s,QoS+隔离) |
| 误判掉线次数/周 | 3–4 次 | 0 |
说人话:跨区域邮件“迟到”抱怨没了,深夜链路抖几下也不会把节点踢出集群。
运行手册(你也能复刻出来)
1)日常巡检
# 复制健康
Test-ReplicationHealth -Identity HK-EX01 | Out-String
Get-MailboxDatabaseCopyStatus * | Sort ReplayQueueLength -Desc | Select -First 5
# 队列长于阈值报警(示例阈值 50)
if ((Get-MailboxDatabaseCopyStatus *).ReplayQueueLength | Measure -Maximum).Maximum -gt 50) {
# 发 Teams/Email 告警(此处接你们的通知平台)
}
2)计划性切换(每季度演练一次)
# 锁定维护窗口
Move-ActiveMailboxDatabase -Server HK-EX01 -ActivateOnServer HK-EX02 -Confirm:$false
# 验证客户端无感、日志无堆积
Test-ReplicationHealth -Identity HK-EX02
3)全站切换(港→新)
# 1. 确认 DAC 开启
(Get-DatabaseAvailabilityGroup DAG-HK-SG).DatacenterActivationMode
# 2. 将见证切到 SG
Set-DatabaseAvailabilityGroup -Identity DAG-HK-SG -WitnessServer "SG-FSW" -WitnessDirectory "C:\DAGWitness"
# 3. 激活 SG 全部 DB
Get-MailboxDatabase | ForEach-Object {
Move-ActiveMailboxDatabase -Identity $_.Name -ActivateOnServer SG-EX01 -Confirm:$false
}
4)滞后副本回滚(事故应急)
# 冻结回放
Set-MailboxDatabaseCopy -Identity "DB01\SG-EX01" -ReplayLagTime 7.00:00:00 -TruncationLagTime 7.00:00:00 -PlaydownAllowed:$false
# 挂载滞后副本到恢复数据库(RDB)...(按你们的恢复流程)
安全与合规提示
- 加密:跨子网复制启用 NetworkEncryption,证书与加密套件符合企业基线。
- 访问控制:见证与 Seeding 共享仅对 Exchange 相关组开放。
- 审计:Cluster 关键变更与 DAG 成员变更纳入变更管理系统。
- 备份:DAG ≠ 备份。坚持做 VSS 级备份与对象级恢复演练。
常见问答(我在现场被问过的)
Q:能不能只用一张网卡?
A:能,但复制与 MAPI 会争抢。我们在高峰时段观测过,单网卡下 P95 复制延迟会被大附件拖到 10s 以上。建议至少 VLAN 隔离,最好物理隔离。
Q:跨区域 RTT 40ms,是否要同步复制?
A:Exchange DAG 是日志级异步复制,不是块级同步;靠的是日志回放队列。核心是把复制网络稳住、把队列压小。
Q:为什么不选存储级复制?
A:Exchange 官方推荐 DAG 自己玩复制,存储级复制常把坏写放大到对等端,还和 VSS/截断有冲突。
两周后,深圳总监把我拉到茶水间,像展示奖杯一样给我看手机:“凌晨发的投标函,1 分钟内对面回了‘收到’,这回稳了。”
我笑了笑没说话。事实上这套东西不神秘:把基础打牢(网络隔离、Cluster 调优、DAG 正确姿势),再用数据反复校验。
如果你也正被跨区域邮件“慢半拍”折腾,不妨照着这份手册在你的香港服务器上一步步复刻:先从 DAG 无管理访问点开始,把跨子网心跳调起来,再把复制网络和业务网络分开。
等你把告警面板铺开,看到队列线一条直的那天,你也会像我一样,默默把咖啡又热了一次。
附:快速核对清单(打印贴机房)
- DAG 无管理访问点 ✅
- Witness/AlternateWitness 配齐、权限 OK ✅
- 复制网络与 MAPI 隔离(物理/VLAN/QoS)✅
- Cluster 跨子网参数(Delay/Threshold)✅
- 复制端口 64327、心跳 3343、SMB 445 放行 ✅
- 滞后副本策略与 SOP ✅
- 监控与演练脚本 ✅