一次FortiGate HA主备切换因会话同步不完整导致业务大规模中断的排查实录

问题背景

我们公司总部机房出口部署了两台 FortiGate 600E 防火墙,以 Active-Passive 模式组成 HA 双机热备集群,承载全公司约 1800 人的互联网访问、总部-分支 IPSec VPN 隧道(6 条)、以及 ERP/OA 等业务系统的对外发布。这套 HA 集群已经稳定运行两年多,期间也经历过两次计划内主备切换(固件升级),均未出现异常。

周三上午 9:15,正值上班高峰期,监控平台突然弹出大量告警——6 条 VPN 隧道状态全部变为 Down,ERP 系统外部访问超时,OA 系统邮件收发中断。与此同时,多个分支机构电话涌入,报告无法访问总部内网资源。整个业务中断持续了约 40 分钟,影响了近 800 名在线用户的正常工作,紧急程度极高。

故障现象

故障发生时,现象非常明确且集中:

1. VPN 隧道全部中断

6 条总部到分支的 IPSec VPN 隧道在 9:15 同时从 Phase 2 Up 变为 Down,FortiGate VPN Monitor 页面显示隧道状态为 “Tunnel Down”,但 Phase 1 仍在协商中。各分支的 FortiGate 日志中出现大量:

1
2
ike: IPSec SA negotiation failed: payload malformed
ike: phase 2 negotiation failed due to timeout

2. ERP 和 OA 系统外部连接中断

Nginx 日志中 9:15 之后请求量骤降至零,直到 9:55 才开始恢复。Grafana 监控图上 TCP 连接数从 2300+ 瞬间跌至 12(仅剩防火墙自身管理连接)。

3. 内部用户互联网访问短暂中断后恢复

内部员工的互联网访问在 9:15 中断了约 30 秒后恢复,但所有需要维持长连接的应用(SSH 会话、WebSocket 推送、SIP 语音通话)全部断开,需要重新建立连接。

4. FortiGate HA 状态异常

登录防火墙管理界面后发现:原主设备(FG-600E-01)已变为 Standby,原备设备(FG-600E-02)已变为 Active。HA 切换确实发生了,但业务并未如预期无缝恢复。

关键日志片段(备机升级为 Active 后):

1
2
3
4
ha: HA member 1 (FG-600E-01) status changed to standby
ha: HA member 2 (FG-600E-02) status changed to active
ha: HA failover triggered by: member 1 heartbeat lost
ha: Session sync incomplete: 48213/112340 sessions synced (43%)

最后一行日志格外引人注目——**会话同步只完成了 43%**,意味着超过 6 万条活跃会话在切换时丢失了。

排查过程

第一步:确认 HA 切换原因

首先搞清楚为什么会发生 HA 切换。登录原主设备(现在是 Standby)查看日志:

1
2
3
system: Thermal shutdown triggered: temperature threshold exceeded (65°C > 55°C)
system: Fan 1 status: failed, Fan 2 status: failed
system: HA heartbeat lost, member transitioning to standby

主设备的两个风扇同时故障,导致设备温度超过阈值触发热保护关机。这是个硬件故障,HA 切换本身是正确的保护行为。

在 FortiGate CLI 上进一步确认:

1
2
3
4
5
6
7
8
9
# execute ha peer status
HA Peer Status:
Member 1 (FG-600E-01): Standby, heartbeat: OK, uptime: 0d 0h 45m (recovered)
Member 2 (FG-600E-02): Active, heartbeat: OK, uptime: 2y 178d

# get system status
Hostname: FG-600E-01
HA Health Status: Standby
Temperature: 42°C (recovered after fan replacement by auto-restart)

主设备在温度恢复正常后自动重启并重新加入了 HA 集群(作为 Standby),但此时业务中断已经发生了。

第二步:深入分析会话同步率为什么只有 43%

这是核心问题。正常情况下,Active-Passive HA 的会话同步应该是实时进行的——主设备上每建立一条新会话,都会同步到备设备。我们检查了 HA 配置:

1
2
3
4
5
6
7
8
9
10
11
12
# show system ha
config system ha
set group-id 10
set group-name "FG-HA-Cluster"
set mode a-p
set password "xxxxxxxx"
set hbdev "ha1" "ha2"
set session-pickup enable
set session-pickup-connectionless enable
set override-disable
set priority 100 (主) / 50 (备)
end

session-pickup enable 是开着的,session-pickup-connectionless enable 也开着(UDP 等 UDP 类会话也会同步)。配置看起来没问题。

但关键参数我们漏掉了session-sync-devha-session-sync-frequency

继续查看完整配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# show system ha full-configuration
config system ha
set group-id 10
set group-name "FG-HA-Cluster"
set mode a-p
set password "xxxxxxxx"
set hbdev "ha1" "ha2"
set hbdev-vlan-id 0
set hbdev-peerip 0.0.0.0
set session-pickup enable
set session-pickup-connectionless enable
set session-sync-dev "ha1" <-- 仅用一条心跳线同步会话
set ha-session-sync-frequency 50 <-- 每50ms同步一批
set override-disable
set priority 100
end

发现了两个问题:

  1. **session-sync-dev 仅指定了 ha1**——会话同步只通过一条心跳线传输,而我们有两条心跳线(ha1 和 ha2),第二条只用来传心跳,没用来传会话数据。
  2. ha-session-sync-frequency 设为 50ms——这意味着每 50ms 才同步一批会话更新。在高并发场景下(112340 条活跃会话),50ms 的间隔会导致同步队列积压。

第三步:计算会话同步吞吐量瓶颈

FortiGate HA 会话同步的工作机制是:主设备每隔 ha-session-sync-frequency 毫秒,将这段时间内新增/变更的会话打包发送到备设备。每批最大传输约 256 条会话更新(取决于底层 TCP 窗口和 MTU)。

我们来算一下:

  • 同步频率:50ms → 每秒 20 批
  • 每批上限:约 256 条
  • 每秒最大同步速率:20 × 256 = 5120 条/秒

但在上班高峰期,新会话建立速率是多少?我们从监控数据中提取:

1
2
3
# 从 FortiGate 的 session 统计看
Active sessions at 09:14: 112340
New sessions per second (average 09:00-09:15): ~18000

每秒新增约 18000 条会话,但同步速率上限只有 5120 条/秒——同步速率远低于会话创建速率,差距约 3.5 倍

这意味着在高峰期,主设备上大量会话根本来不及同步到备设备。当切换发生时,备设备上的会话表只是”最近同步过来的那部分”,而不是完整的活跃会话集合。

此外还有一个问题:FortiGate 的会话同步是增量同步,不是全量同步。主设备只在会话建立时发送一次同步消息,后续的状态变更(如 TCP 序列号更新、窗口大小变化)不会再同步。所以即使同步速度够快,长连接的中间状态信息也是缺失的。

第四步:验证心跳通道带宽

两条心跳线分别连接在不同端口上:

1
2
ha1: port3 (1Gbps RJ45)
ha2: port4 (1Gbps RJ45)

心跳线用的是千兆端口,但 session-sync-dev 只指定了 ha1,意味着所有会话同步数据只走 port3 一条链路。实际测量 port3 在高峰期利用率:

1
2
3
# fnsysctl ifconfig port3
port3: TX packets 847320, TX bytes 634MB (09:00-09:15)
port3: RX packets 823100, RX bytes 618MB

15 分钟内 TX 634MB → 平均速率约 7Mbps。对于千兆链路来说带宽远没有用满,但问题不在带宽,而在同步频率太低导致每批数据量不够

如果把 ha-session-sync-frequency 从 50ms 改为 1ms(最小值),每秒同步频率从 20 批提升到 1000 批,同步速率上限变为 1000 × 256 = 256000 条/秒,远超高峰期新增速率。同时如果把 session-sync-dev 改为同时使用 ha1 和 ha2,吞吐量还能翻倍。

第五步:检查历史切换记录

排查到这里,不禁要问:之前两次计划内切换为什么没出问题?我们查看 HA 事件历史:

1
2
3
4
# execute ha history
1. 2024-03-15 02:00 - Planned failover (firmware upgrade), session sync: 98.7%
2. 2025-01-10 03:00 - Planned failover (firmware upgrade), session sync: 99.2%
3. 2026-07-02 09:15 - Unplanned failover (thermal shutdown), session sync: 43%

前两次切换都是在凌晨低峰期进行的(凌晨 2-3 点),活跃会话只有约 3000 条,同步完全来得及。而这次切换发生在早高峰,活跃会话 11 万条,同步速率跟不上,就暴露了这个长期存在的隐患。

本质上是:配置在低峰期”够用”,但高峰期不够用,平时根本发现不了。

第六步:查看备机切换后的会话重建情况

备机成为 Active 后,丢失的会话需要由客户端重新建立。我们统计了业务恢复时间线:

时间 事件 活跃会话数
09:15 HA 切换完成 48213(同步过来的)
09:16 VPN Phase 1 重新协商开始 48500
09:20 6 条 VPN 隧道恢复 4 条 52300
09:30 VPN 全部恢复 61200
09:55 业务连接基本恢复 108000
10:20 会话数恢复到正常水平 112000+

从 48213 恢复到正常水平用了约 1 小时,但核心业务(VPN、ERP)在 40 分钟后才基本可用。原因是 VPN 隧道的 IKE 协商需要多轮密钥交换,加上分支 FortiGate 的 DPD(Dead Peer Detection)检测间隔为 30 秒,隧道重建有较长的等待窗口。

解决方案

紧急止血(已完成)

HA 切换已经发生,无法回滚。业务通过自然重连逐步恢复,VPN 隧道在 DPD 触发后自动重建。40 分钟后业务基本恢复,这是本次故障的实际恢复时间。

配置优化(根治)

1. 提升会话同步频率

ha-session-sync-frequency 从 50ms 改为 1ms(最小值),大幅提升同步吞吐量:

1
2
3
4
# FortiGate CLI
config system ha
set ha-session-sync-frequency 1
end

修改后,同步速率上限从 5120 条/秒提升到 256000 条/秒,完全覆盖高峰期 18000 条/秒的创建速率。

2. 会话同步使用双心跳通道

session-sync-dev 改为同时使用 ha1 和 ha2,使会话同步数据可以走两条链路,提供冗余和更高吞吐:

1
2
3
config system ha
set session-sync-dev "ha1" "ha2"
end

3. 启用 TCP 会话状态同步

FortiGate 7.0+ 版本支持更精细的 TCP 状态同步,可以通过以下配置启用:

1
2
3
4
5
config system ha
set session-pickup enable
set session-pickup-connectionless enable
set session-pickup-expected enable # 启用 expected-session 同步
end

4. 优化 HA 心跳参数

1
2
3
4
config system ha
set hb-interval 500 # 心跳间隔从默认2s改为500ms
set hb-lost-threshold 3 # 丢失3次心跳判定故障(1.5秒而非6秒)
end

这样主设备故障时备机能更快检测到并切换,减少中断窗口。

5. VPN 階道 DPD 间隔优化

各分支 FortiGate 的 DPD 检测间隔从 30 秒改为 5 秒:

1
2
3
4
5
6
7
8
# 各分支 FortiGate
config vpn ipsec phase1-interface
edit "HQ-VPN"
set dpd on
set dpd-retryinterval 5
set dpd-retrycount 3
next
end

隧道中断后能在 15 秒内检测到并触发重建,而不是等 90 秒。

6.风扇故障修复

联系 FortiGate TAC 更换主设备的两个故障风扇,同时对备设备也做预防性检查。FortiGate 600E 的风扇模块是可插拔的,更换后设备温度恢复正常。

完整优化后的 HA 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
config system ha
set group-id 10
set group-name "FG-HA-Cluster"
set mode a-p
set password "xxxxxxxx"
set hbdev "ha1" "ha2"
set hb-interval 500
set hb-lost-threshold 3
set session-pickup enable
set session-pickup-connectionless enable
set session-pickup-expected enable
set session-sync-dev "ha1" "ha2"
set ha-session-sync-frequency 1
set override-disable
set priority 100
end

根因分析

本次故障的根本原因是 HA 会话同步配置未针对高峰期负载进行优化,形成了”低峰期够用、高峰期不够用”的隐性缺陷。

具体分解:

  1. 同步频率过低ha-session-sync-frequency = 50ms 导致每秒最多同步 5120 条会话,而高峰期每秒新增约 18000 条,差距 3.5 倍。大量会话在主设备上建立但来不及同步到备设备。

  2. 同步通道单线传输session-sync-dev 仅指定 ha1,没有利用第二条心跳线 ha2 的带宽,浪费了冗余资源。

  3. 增量同步机制局限:FortiGate 的会话同步只传递会话建立事件,不传递中间状态变更。即使同步速度够快,长连接在切换后的状态信息(TCP 序列号、窗口等)也是不完整的,可能导致部分连接虽然”存在”但无法继续正常通信。

  4. 风扇硬件故障是触发因素:两台风扇同时失效导致主设备过热保护关机,触发非计划切换。但风扇故障只是导火索,真正的爆炸点是长期存在的会话同步瓶颈。

  5. 缺乏高峰期验证:前两次计划切换都在凌晨低峰期进行,同步率 98%+ 给了团队”HA 配置没问题”的错误信心。从未在高峰期做过 HA 切换演练。

预防措施

1. HA 配置基线标准化

将上述优化后的 HA 配置纳入 FortiGate 标准配置模板,所有新部署和现有集群统一升级。特别关注三个关键参数:

参数 原值 优化值 说明
ha-session-sync-frequency 50ms 1ms 同步频率最大化
session-sync-dev ha1 ha1+ha2 双通道冗余
hb-interval 2000ms 500ms 快速故障检测

2. 建立 HA 同步率监控

在 Zabbix 中新增 FortiGate HA 同步率监控项:

1
2
3
4
5
6
7
8
# FortiGate SNMP/CLI 获取同步会话数
fnsysctl cat /proc/ha_stats | grep "sessions_synced"

# 对应的 Zabbix Item
# Type: SNMP or External Check
# Key: fortigate.ha.session.sync.rate
# Expression: sessions_synced / active_sessions_total * 100
# Trigger: sync rate < 80% for 5 minutes → P1 alert

同步率低于 80% 立即告警,让运维在切换发生前就知道同步不完整。

3. 定期高峰期 HA 演练

每季度一次,在上班高峰期(上午 9-10 点)执行计划内 HA 切换演练,验证:

  • 会话同步率是否 ≥ 95%
  • VPN 阧道重建时间是否 ≤ 30 秒
  • 业务恢复时间是否 ≤ 60 秒
  • 监控告警是否正常触发

演练流程:提前通知全员 → 手动触发主备切换 → 记录恢复时间 → 回切并验证。

4. 硬件健康监控

FortiGate 600E 支持通过 SNMP 获取风扇状态和温度:

1
2
3
4
# Zabbix Item
fgFanStatus[port3] # 风扇运行状态
fgSysTemperature # 设备温度
# Trigger: fan failed OR temperature > 50°C → P2 alert

风扇故障能在切换前被发现,避免非计划切换。

5. FortiGate 固件升级

当前版本 FortiOS 7.0.13,7.2 版本改进了 HA 会话同步机制(支持更高效的批量同步和 TCP 状态同步)。计划在下个维护窗口升级到 7.2.6。

6. 文档和 SOP 更新

更新以下运维文档:

  • FortiGate HA 配置标准模板:包含所有优化参数
  • HA 故障应急预案:明确切换后 5 分钟内检查同步率、10 分钟内评估业务影响
  • HA 演练 SOP:季度演练流程和验收标准
  • 硬件巡检清单:增加风扇状态、温度、电源冗余检查项

总结

这次故障让我深刻认识到一个教训:HA 双机热备 ≠ 业务零中断,配置”能跑”不等于配置”可靠”。

两年多来 HA 一直”正常工作”,是因为前两次切换恰好在低峰期,同步瓶颈从未被暴露。当真正的非计划切换发生在高峰期时,11 万条会话只同步了 43%,业务中断 40 分钟。这就像一辆车平时在市区 30km/h 没问题,上了高速才发现刹车不够力。

几个关键教训:

  1. HA 配置必须按高峰期负载设计,同步速率要远大于高峰期会话创建速率,留足余量。
  2. HA 演练必须在高峰期做,低峰期演练只能验证切换流程,不能验证业务连续性。
  3. 会话同步率必须纳入持续监控,不能等到切换时才发现同步不完整。
  4. 硬件故障(风扇、电源、磁盘)是 HA 切换的最常见触发因素,预防性硬件监控比事后切换恢复更重要。

FortiGate HA 的会话同步是个容易被忽视的配置细节,很多团队只关注 session-pickup enable 是否打开,却忽略了同步频率、同步通道、TCP 状态同步这些影响实际同步效果的关键参数。希望这篇排查记录能帮助同行们重新审视自己的 HA 配置,别等到故障发生才追悔莫及。