mode 0纯轮询发包,需交换机允许多端口学习同一mac且禁用stp与端口安全;mode 1无负载均衡,仅主备切换;mode 4依赖lacp协商与hash策略对齐才能实现流量分摊。

mode 0(balance-rr)发包顺序固定,switch 不用配 LACP 但必须允许同 MAC 多端口学习
mode 0 是纯轮询,arp_interval 和 miimon 只管链路检测,不参与负载决策。每发一个包就换一个 slave,不管目的 IP、端口或流量大小。所以 switch 看到同一个源 MAC 地址的帧从不同物理口进来,必须能正确学习并转发回包——否则会丢包或单向通。
常见错误现象:tcpdump 在 server 上能看到出包分在两个口,但 client 收不到响应;或者 ping 通但大流量时大量重传。
- switch 端口不能开 STP(尤其 blocking 状态会拦住某个 slave 的回包)
- 交换机要关闭「MAC 地址严格绑定端口」类功能(比如 Cisco 的
switchport port-security或 H3C 的mac-address max-mac-count 1) - 不需要配置 LACP,但所有 bonding 成员口必须处于同一 VLAN、相同双工/速率模式
mode 1(active-backup)根本不存在负载均衡,LACP 配了也白配
mode 1 只有一个 active slave,其余全 standby,fail_over_mac 和 primary 参数只影响故障切换行为,和流量分发无关。哪怕你在 switch 上配了 LACP group,Linux 也不会发 LACPDU,switch 侧看到的是独立端口,LACP 状态永远是 individual 或 down。
使用场景:只要求高可用、不关心吞吐提升,比如管理网口、带外通道。
- 别指望靠 mode 1 + LACP 实现带宽叠加,实测
iperf3单流跑不满一个口 - 如果 switch 强制要求 LACP 才放行端口(如某些云厂商接入交换机),mode 1 直接不通,得换 mode 4
-
arp_validate设为all可缓解 ARP 探测失败导致误切的问题,但不改变无负载均衡的本质
mode 4(802.3ad / LACP)必须两端都启用 LACP,且 hash 策略需对齐
mode 4 真正依赖 LACP 协商,Linux 内核通过 lacp_rate(slow/fast)和 xmit_hash_policy 控制行为。switch 侧必须创建 LAG 并启用 LACP(不是静态 trunk),且双方超时参数要兼容(比如 Linux 设 lacp_rate fast,switch 不能只支持 slow)。
关键点在于 hash:Linux 默认用 xmit_hash_policy layer2(只看 MAC),这意味着同一对主机间所有流量永远走同一个 slave。想真正分散,得改策略:
-
xmit_hash_policy layer2+3:基于源/目的 MAC + IP,适合多客户端访问同一 server -
xmit_hash_policy layer3+4:再加 TCP/UDP 端口,单客户端多连接也能分摊(如浏览器并发请求) - switch 侧 hash 策略也要匹配,比如 Cisco 用
port-channel load-balance src-dst-ip,不能一边 layer2 一边 layer3+4
性能影响:layer3+4 hash 计算稍重,但在现代 CPU 上几乎无感;但若应用大量使用相同五元组(如 NAT 后的客户端),仍可能局部打满某 slave。
为什么 bond0 的 TX 流量看起来没分摊?先查 cat /proc/net/bonding/bond0
很多人直接看 ifconfig 或 ip -s link show bond0,但这些只显示聚合口总流量,看不出 slave 分布。真正要看的是内核 bonding 模块的实时状态。
执行命令后重点检查三处:
-
Slave Interface: eth0下的Link Failure Count—— 非零说明链路抖动,可能被踢出 active list -
Aggregator ID:—— mode 4 下必须所有 slave 显示相同 ID,否则 LACP 协商失败 -
Currently Active Slave:—— mode 1 下只有一行有值;mode 4 下应全部显示None(表示由 hash 调度,非手动指定)
容易被忽略的是:即使配置正确,短连接、小包、或目标单一的服务(如 DNS 查询)天然难分摊。别只盯着数字,用 ss -i 看实际 socket 发送队列分布,或在每个 slave 上 tcpdump -i eth0 -c 100 'tcp[tcpflags] & (TCP-SYN|TCP-ACK) != 0' 对比 SYN 包数量更直观。










