tc 流量控制:用 netem 模拟延迟、丢包,用 qdisc 整形
更新时间:2026-09-19。Linux 的
tc(traffic control)通过队列规则(qdisc)管理网卡收发队列,其中 netem(network emulator)能人为注入延迟、抖动、丢包、乱序,是测试超时/重试/熔断和混沌网络实验的底层工具(Chaos Mesh 的 NetworkChaos 底层就是它)。
一、netem 常用损伤
bash
# 出向(egress)固定加 100ms 延迟
sudo tc qdisc add dev eth0 root netem delay 100ms
# 100ms ± 20ms 抖动,并用 correlation 模拟突发相关性
sudo tc qdisc change dev eth0 root netem delay 100ms 20ms 25%
# 丢包 5%
sudo tc qdisc add dev eth0 root netem loss 5%
# 丢包 5%,相邻丢包相关性 25%(更接近真实突发丢包)
sudo tc qdisc add dev eth0 root netem loss 5% 25%
# 包损坏/重复/乱序
sudo tc qdisc add dev eth0 root netem corrupt 1%
sudo tc qdisc add dev eth0 root netem duplicate 1%
sudo tc qdisc add dev eth0 root netem delay 100ms reorder 25%
# 组合:延迟 + 丢包 + 限速
sudo tc qdisc add dev eth0 root netem delay 80ms 10ms loss 2% rate 10mbit| 参数 | 作用 |
|---|---|
delay TIME [JITTER [CORRELATION]] | 延迟/抖动/相关性 |
loss PCT [CORR] | 丢包比例与突发相关性 |
corrupt/duplicate/reorder | 损坏/重复/乱序 |
rate | 限速 |
distribution normal/pareto | 延迟分布(正态/重尾,更真实) |
二、查看与删除(务必记得)
bash
tc qdisc show dev eth0 # 查看当前规则
tc -s qdisc show dev eth0 # 带统计(丢包/字节计数)
sudo tc qdisc del dev eth0 root # 删除,恢复正常网络netem 是强制生效的,不删就一直在损伤网络,在生产/远程主机上操作前一定要留好「自动恢复」(如 sleep 60 && tc qdisc del ... &),避免把自己 SSH 断开且无法恢复。
三、只管出方向,入向怎么办
netem 加在 root(egress 发送队列),直接只影响发出的包。要对接收方向做损伤,常用 ifb(Intermediate Functional Block)把入向流量重定向到一个虚拟设备,再在它的 egress 上挂 netem:
bash
sudo modprobe ifb numifbs=1
sudo ip link set ifb0 up
sudo tc qdisc add dev eth0 ingress
sudo tc filter add dev eth0 parent ffff: protocol ip u32 \
match u32 0 0 action mirred egress redirect dev ifb0
sudo tc qdisc add dev ifb0 root netem delay 100ms loss 2%测试客户端↔服务端时,通常只在一侧出向加延迟就足以让往返变慢(ACK 也被延后),但要精确控制双向损伤需两侧/ifb 配置。
四、netem 与 htb/tbf 的分工
- netem:制造损伤(延迟/丢包/乱序),目的是模拟坏网络做容错测试。
- htb / tbf / fq_codel:流量整形与调度(限速、分类、带宽分配、bufferbloat 治理),目的是管理好网络。
- 可级联:父 qdisc 用 htb 限速分类,子 qdisc 挂 netem 损伤:
bash
# htb 整形 + 子类挂 netem(示例结构)
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 50ms五、典型测试场景
- 超时与重试:给下游调用加 200ms 延迟,验证连接/读超时、重试风暴与熔断是否生效。
- 弱网体验:模拟移动网络高抖动、0.5%~5% 丢包,观察 P99、重传(配合 ss、tcpdump)。
- 混沌演练:用 netem/Chaos Mesh 注入网络分区(配合 DROP)验证脑裂防护与跨 AZ 容灾,见 RTO/RPO。
- 乱序/重复:检验协议栈和应用对异常包序的鲁棒性。
坑
- 加完规则忘记删,机器持续处于弱网,影响真实业务。
- 远程操作直接在管理网卡加高丢包,把自己 SSH 切断;应加定时恢复或在业务网卡/容器内做。
- 以为 netem 能直接限入向,实际只在 egress,入向要 ifb。
- 用固定延迟测试,真实网络有抖动和重尾分布,结论偏乐观,应加 jitter/distribution。
- 在生产物理机做全局损伤波及无关服务;容器环境优先用 NetworkChaos 限定 Pod 范围(即舱壁/爆炸半径思想)。
总结
tc 通过 qdisc 管理网卡队列,netem 可在出向注入 delay/jitter、loss、corrupt、reorder 和 rate 限速来模拟弱网,是验证超时、重试、熔断和混沌网络故障的底层手段,用 tc qdisc show 查看、del 恢复并务必设置自动回滚;它默认只作用于发送方向,入向需借助 ifb 重定向,而 htb/tbf 负责真实的带宽整形与调度,两者可级联——使用时严格控制作用范围,避免误伤生产和远程管理链路。