Linux双ISP动态负载均衡本质是ECMP+健康探测+路由重写,需配合策略路由防非对称路径,单靠ip route add无法自动故障切换。

Linux 服务器上用 ip route add default nexthop 实现双 ISP 公网链路的动态负载均衡,本质上是利用内核的 ECMP(Equal-Cost Multi-Path)能力,但需注意:ip route add default scope global nexthop via ... 本身只支持静态等价路径分发,不自动感知链路状态变化,因此“动态”必须靠外部机制补足。真正可用的方案是“ECMP + 健康探测 + 路由重写”,而非单靠一条 ip route 命令。
以下是关键实现逻辑与实操要点:
一、基础 ECMP 负载分发(静态层面)
确保两条出口链路满足 ECMP 条件(同 metric、同 scope、下一跳可达),再添加等权默认路由:
ip route add default scope global \ nexthop via 203.0.113.1 dev eth0 weight 1 \ nexthop via 198.51.100.1 dev eth1 weight 1
- ✅ 有效前提:两个下一跳网关(ISP 提供的出口网关)必须能被本机 ARP 解析且 ICMP 可达;
- ✅ 内核会按流哈希(源/目的 IP+端口)分发数据包,实现连接级均衡(非包级);
- ❌ 不自动踢除故障链路 —— 若
eth1网关宕机,流量仍会按哈希继续发往该不可达下一跳,导致丢包。
二、让负载“动态”起来:必须引入健康探测
单纯 ip route 无法动态响应链路故障,需配合脚本或工具实时检测并重写路由:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
轻量方案(推荐):用
ping+ip route replace脚本轮询# 检测网关连通性(各发3个包,超时1秒) ping -c3 -W1 203.0.113.1 >/dev/null && UP0=1 || UP0=0 ping -c3 -W1 198.51.100.1 >/dev/null && UP1=1 || UP1=0 # 动态生成路由:仅保留存活链路,weight 自动归一化(如仅剩1条,则 weight=1) if [ $UP0 -eq 1 ] && [ $UP1 -eq 1 ]; then ip route replace default scope global \ nexthop via 203.0.113.1 dev eth0 weight 1 \ nexthop via 198.51.100.1 dev eth1 weight 1 elif [ $UP0 -eq 1 ]; then ip route replace default via 203.0.113.1 dev eth0 elif [ $UP1 -eq 1 ]; then ip route replace default via 198.51.100.1 dev eth1 else ip route flush default # 全挂则清空,避免黑洞 fi- 放入 cron 每 10 秒执行一次(
*/10 * * * * /path/to/check.sh); - 需搭配
ip rule配合源地址策略,避免回程路径不一致(见下一点)。
- 放入 cron 每 10 秒执行一次(
三、解决“非对称路由”和“原路返回”问题
双 ISP 场景下,若不约束回程路径,容易出现请求从电信进、响应从联通出,被运营商丢弃(uRPF 检查失败)。必须启用策略路由:
- 为每个出口网卡配置独立路由表:
echo "100 tab_chinanet" >> /etc/iproute2/rt_tables echo "200 tab_cnc" >> /etc/iproute2/rt_tables ip route add default via 203.0.113.1 dev eth0 table tab_chinanet ip route add default via 198.51.100.1 dev eth1 table tab_cnc
- 绑定源地址到对应路由表:
ip rule add from 203.0.113.100/32 table tab_chinanet ip rule add from 198.51.100.200/32 table tab_cnc
- 对外服务(如 Web)需绑定监听地址到具体 IP,确保响应从同一接口发出。
四、更健壮的替代方案(生产推荐)
- 使用
bird或frr守护进程:内置 BGP/OSPF 或静态路由 + bfd 探测,自动收敛; - 用
keepalived+iproute2:通过 vrrp 状态联动路由切换; - 避免纯 shell 脚本管理核心路由 —— 故障窗口大、竞态风险高。
不复杂但容易忽略:ECMP 分流粒度是“流”不是“包”,单 TCP 连接始终走同一条链路;真正的带宽叠加需靠多连接(如浏览器并发、curl 多线程)或应用层调度。


















