跳到主要内容

TC (Traffic Control) 网络模拟

1. 基础概念

1.1. 什么是 TC

TC (Traffic Control) 是 Linux 内核提供的流量控制工具,可以模拟各种网络条件。

1.2. 基本命令结构

# 基本语法
tc qdisc [add|change|replace|del] dev <设备> [root|parent <句柄>] [网络模拟参数]

# 查看当前规则
tc qdisc show dev <设备>

# 删除所有规则
tc qdisc del dev <设备> root

2. 网络延迟模拟

2.1. 固定延迟

# 添加 100ms 固定延迟
tc qdisc add dev eth0 root netem delay 100ms

# 修改延迟为 200ms
tc qdisc change dev eth0 root netem delay 200ms

# 替换现有规则
tc qdisc replace dev eth0 root netem delay 150ms

2.2. 随机延迟波动

# 2.2.1. 100ms ± 20ms 随机波动
tc qdisc add dev eth0 root netem delay 100ms 20ms

# 2.2.2. 100ms ± 50ms,延迟相关性 25%
tc qdisc add dev eth0 root netem delay 100ms 50ms 25%
# 0% 的延迟相关性,表示每个延迟都是随机生成,和上一个没有关系。默认是0%
# 25% 前数据包延迟有25%的可能性跟随前一个数据包的延迟趋势

2.3. 延迟分布模型

# 2.3.1. 正态分布延迟
tc qdisc add dev eth0 root netem delay 100ms 30ms distribution normal

# 2.3.2. 帕累托分布延迟
tc qdisc add dev eth0 root netem delay 100ms 30ms distribution pareto

3. 其他网络条件模拟

3.1. 丢包模拟

# 3.1.1. 5% 丢包
tc qdisc add dev eth0 root netem loss 5%

# 3.1.2. 5% 丢包,相关性 25%
tc qdisc add dev eth0 root netem loss 5% 25%

3.2. 带宽限制

# 3.2.1. 限制为 1Mbps
tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms

# 3.2.2. 使用 HTB 进行精细控制
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit

3.3. 数据包损坏和重复

# 3.3.1. 2% 的数据包损坏
tc qdisc add dev eth0 root netem corrupt 2%

# 3.3.2. 3% 的数据包重复
tc qdisc add dev eth0 root netem duplicate 3%

# 3.3.3. 5% 的数据包重排序
tc qdisc add dev eth0 root netem delay 50ms reorder 10%

4. 组合网络条件

4.1. 复杂网络模拟

# 4.1.1. 延迟 + 丢包组合
tc qdisc add dev eth0 root netem delay 100ms loss 3%

# 4.1.2. 完整恶劣网络模拟
tc qdisc add dev eth0 root netem \
delay 300ms 100ms 25% \
loss 15% 30% \
duplicate 2% \
corrupt 1% \
reorder 10% 50%

4.2. 特定场景模拟

# 4.2.1. 移动网络模拟
tc qdisc add dev eth0 root netem \
delay 100ms 50ms 25% \
loss 1% 30% \
duplicate 0.5%

# 4.2.2. 卫星链路模拟
tc qdisc add dev eth0 root netem \
delay 500ms 100ms \
loss 0.5% \
duplicate 0.1%

5. 针对特定流量的控制

5.1. 基于端口的控制

# 5.1.1. 创建分类队列
tc qdisc add dev eth0 root handle 1: prio
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 100ms
tc qdisc add dev eth0 parent 1:2 handle 20: netem delay 50ms

# 5.1.2. HTTP 流量高延迟
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 80 0xffff flowid 1:1

# 5.1.3. SSH 流量中等延迟
tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip dport 22 0xffff flowid 1:2

5.2. 基于 IP 的控制

# 5.2.1. 为特定目标 IP 添加延迟
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 192.168.1.100 flowid 1:1

6. 延迟效果验证方法

6.1. 基础 ping 测试

# 6.1.1. 基本延迟测试
ping -c 10 google.com

# 6.1.2. 显示时间戳
ping -D -c 10 8.8.8.8

# 6.1.3. 简化统计输出
ping -c 20 -q 8.8.8.8

6.2. 解析 ping 输出

--- 8.8.8.8 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 98.123/102.456/105.789/2.123 ms
  • min: 最小延迟
  • avg: 平均延迟
  • max: 最大延迟
  • mdev: 延迟波动

6.3. 路径分析工具

# 6.3.1. 显示路径每跳延迟
traceroute www.baidu.com

# 6.3.2. 实时路径监控
mtr google.com

# 6.3.3. 生成报告
mtr -r -c 10 google.com

7. TCP/HTTP 延迟测试

7.1. curl 详细时间分析

# 7.1.1. 显示连接各阶段时间
curl -w "
DNS解析: %{time_namelookup}
连接建立: %{time_connect}
TLS握手: %{time_appconnect}
传输开始: %{time_starttransfer}
总时间: %{time_total}
" -o /dev/null -s https://www.baidu.com

7.2. 使用时间模板文件

# 7.2.1. 创建时间格式文件
cat > time_format.txt << EOF
时间统计:
DNS解析: %{time_namelookup} s
连接建立: %{time_connect} s
TLS握手: %{time_appconnect} s
首字节: %{time_starttransfer} s
总时间: %{time_total} s
EOF

# 7.2.2. 使用格式文件
curl -w "@time_format.txt" -o /dev/null -s https://google.com

8. 专业性能测试

8.1. iperf3 测试

# 8.1.1. 服务器端
iperf3 -s

# 8.1.2. 客户端测试带宽和延迟
iperf3 -c server_ip -t 30 -i 1

# 8.1.3. UDP 测试(更准确反映延迟)
iperf3 -c server_ip -u -b 10M -t 30

8.2. 实时监控命令

# 8.2.1. 查看 TC 规则状态
tc -s qdisc show dev eth0

# 8.2.2. 实时监控队列统计
watch -n 1 'tc -s qdisc show dev eth0'

# 8.2.3. 查看详细包统计
tc -s qdisc ls dev eth0

9. 自动化测试脚本

9.1. 完整的对比测试脚本

#!/bin/bash
TARGET="8.8.8.8"
INTERFACE="eth0"
TEST_DELAYS=("50ms" "100ms" "200ms")

echo "=== 网络延迟模拟测试 ==="
echo "目标主机: $TARGET"
echo "网络接口: $INTERFACE"
echo

# 9.1.1. 基准测试
echo "1. 基准测试(无延迟模拟):"
ping -c 5 -q $TARGET | grep rtt
echo

for delay in "${TEST_DELAYS[@]}"; do
echo "2. 设置 $delay 延迟:"
tc qdisc add dev $INTERFACE root netem delay $delay 2>/dev/null

# 9.1.2. 测试当前延迟
echo "当前延迟效果:"
ping -c 5 -q $TARGET | grep rtt

# 9.1.3. 测试 TCP 连接延迟
echo "TCP 连接延迟:"
curl -w "总时间: %{time_total}s\n" -o /dev/null -s http://$TARGET

echo
sleep 2

# 9.1.4. 清理规则
tc qdisc del dev $INTERFACE root 2>/dev/null
done

echo "=== 测试完成 ==="

9.2. 延迟波动验证脚本

#!/bin/bash
TARGET="8.8.8.8"
INTERFACE="eth0"
DURATION=30

echo "测试延迟波动效果..."
echo "设置: 100ms ± 50ms 延迟波动"
tc qdisc add dev $INTERFACE root netem delay 100ms 50ms

echo "开始收集延迟数据..."
ping -c $DURATION $TARGET | grep 'time=' | awk -F'[= ]' '{print $8}' > latency_data.txt

echo "延迟统计:"
awk '
{
delays[NR] = $1
sum += $1
}
END {
if (NR > 0) {
avg = sum / NR
asort(delays)
mid = int(NR / 2)
if (NR % 2) {
median = delays[mid + 1]
} else {
median = (delays[mid] + delays[mid + 1]) / 2
}
print "样本数: " NR
print "平均延迟: " avg " ms"
print "中位数: " median " ms"
print "最小延迟: " delays[1] " ms"
print "最大延迟: " delays[NR] " ms"
print "波动范围: " (delays[NR] - delays[1]) " ms"
}
}' latency_data.txt

# 9.2.1. 清理
tc qdisc del dev $INTERFACE root 2>/dev/null
rm latency_data.txt

10. 高级监控和分析

10.1. 实时延迟监控

# 10.1.1. 持续监控并记录
ping $TARGET | while read pong; do
echo "$(date '+%H:%M:%S'): $pong"
done

# 10.1.2. 提取延迟数值监控
ping $TARGET | awk -F'[= ]' '/time=/ {print strftime("%H:%M:%S") " - " $(NF-1) "ms"}'

10.2. TC 统计信息解读

# 10.2.1. 查看详细统计
tc -s qdisc show dev eth0

# 10.2.2. 输出示例解读:
qdisc netem 8001: root refcnt 2 limit 1000 delay 100.0ms 10.0ms
Sent 123456 bytes 1000 pkt (dropped 50, overlimits 0 requeues 0)

# 10.2.3. 关键指标:
# - Sent: 发送的数据量和包数
# - dropped: 丢包数量
# - overlimits: 超过限制的包数

11. 故障排除和恢复

11.1. 常见问题处理

# 11.1.1. 强制删除所有规则
tc qdisc del dev eth0 root 2>/dev/null || true

# 11.1.2. 检查设备状态
ip link show dev eth0

# 11.1.3. 验证规则是否生效
tc qdisc show dev eth0

11.2. 安全恢复脚本

#!/bin/bash
INTERFACE="eth0"

echo "正在恢复网络设置..."
tc qdisc del dev $INTERFACE root 2>/dev/null

# 11.2.1. 验证恢复
echo "当前网络规则:"
tc qdisc show dev $INTERFACE

echo "网络延迟测试:"
ping -c 3 -q 8.8.8.8 | grep rtt

12. 最佳实践建议

测试前准备

  • 测试前备份: 记录原始网络设置

  • 环境检查: 确认网络接口和设备状态

测试执行

  • 逐步验证: 从简单延迟开始,逐步增加复杂度
  • 多工具验证: 使用 ping、curl、traceroute 等多种工具交叉验证

生产环境注意事项

  • 生产环境谨慎: 在生产环境测试时设置超时和自动恢复
  • 文档记录: 记录测试参数和结果,便于问题排查

性能监控

  • 实时监控: 使用 watch 命令实时监控 TC 统计信息
  • 数据记录: 保存测试数据用于后续分析