Netem
Netem 通过模拟广域网的特性,位测试协议提供了网络仿真功能。当前版本模拟传输延迟、丢包、重复包和包乱序。
netem 内核组件在以下情况下启用:
Networking -->
Networking Options -->
QoS and/or fair queuing -->
Network emulator
Netem 由命令行工具 “tc” 控制,它是 iproute2 工具包的一部分。
tc命令使用/usr/lib/tc目录中的共享库和数据文件。
示例
模拟广域网延迟
这是一个最简单的例子,它只是给所有从本地以太网传出的数据增加了一个固定的延迟量。
# tc qdisc add dev eth0 root netem delay 100ms
现在,对本地网络上的主机进行一次简单的 ping 测试,你应该会看到增加 100 ms的延迟。
迟延会受到内核时钟分辨率(Hz)的限制。在大多数 2.4系统上(指Linux内核版本),系统
时钟以以 100Hz 的频率运行,允许以 10ms 的增量进行延迟。在 2.6 系统中,此值从
100~1000Hz 范围内波动。
后面的示例只是更改参数而不重新加载qdisc。
也就是 tc 指令使用 change 指令,而不是使用 add 指令。
真实的广域网环境是易变的,因此 netem 支持添加随机变化。
# tc qdisc change dev eth0 root netem delay 100ms 10ms
这导致增加的时延调整为 100±10 ms。然而,延迟也不是完全随机的,因此若要进行仿真,
还存在一个相关值。(也就是随机延迟出现的概率)
# tc qdisc change dev eth0 root netem delay 100ms 10ms 25%
这导致增加的延迟调整为100ms±10ms,并且每一次下一个元素的值有25%的概率取决于
上一次元素的值(另外75%就是随机延迟,相关值越大,说明网络状况比较稳定,不易
发现波动)。这不是真正的统计相关性,只是近似值而已。
延迟分布
事实上,网络的延迟通常不是均匀的。更常见的是使用类似于正态分布的函数来描述
延迟的变化。
Netem 规定使用表格的方式来指定非均匀分布。
# tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal
实际表(normal、pareto、paretonormal)作为iproute2编译的一部分生成,并放置在/usr/lib/tc中;因此,通过一些努力,您可以根据实验数据进行自己的分布。
丢包
tc 命令中以百分比的形式规定随机丢包的形式。最小的可能非零值为:
1 / 0XFFFFFFFF = 0.0000000232%
# tc qdisc change dev eth0 root netem loss 0.1%
还可以添加相关性(可选)。这使得随机数生成器的随机性更小,并可用于模拟数据包的突发丢失。
# tc qdisc change dev eth0 root netem loss 0.4% 25%
原理可参见延迟分布,这种情况下丢包发生的区域会更加集中,即突发丢包
警告
当本地使用丢失时(不是在网桥或路由器上),丢失将报告给上层协议。这可能会导致TCP重新发送,并表现得好像没有丢失一样。当测试协议响应丢失时,最好在网桥或路由器上使用netem。
重包
数据包重复的指定方式与数据包丢失的指定方式相同。
# tc qdisc change dev eth0 root netem duplicate 1%
数据包损坏
使用 corrupt 选项,随机噪声可以被模拟 (在 2.6.16 内核版本之后 )。
这会在数据包中的随机偏移量处引入一个位错误。
# tc qdisc change dev eth0 root netem corrupt 0.1%
包重排序
有两种不同的方法可以指定重新排序。第一种方法gap使用固定序列,并每N个数据包重新排序一次。一个简单的使用例子如下:
# tc qdisc change dev eth0 root netem gap 5 delay 10ms
这会导致每5个(第10个、第15个,…)数据包立即发送,而每其他数据包延迟10毫秒。这对于基本协议测试(如重新组装)是可预测和有用的。(例如一些基于 UDP 的协议,需要对数据包进行乱序重排)
第二种形式的重新排序更像现实生活。它会导致一定比例的数据包顺序错误。
# tc qdisc change dev eth0 root netem delay 10ms reorder 25% 50%
在此示例中,25%的数据包(相关性为50%)将立即发送,其他数据包将延迟10ms发送。
如果随机延迟值不符合顺序,新版本的netem也将重新排序数据包。以下情况将导致一些重新排序:
# tc qdisc change dev eth0 root netem delay 100ms 75ms
这是主要由于 networking 默认采取 pfifo , 即先进先出,所以有出队的顺序关系
速率控制
netem qdisc可以使用速率功能控制带宽。请小心确保netem qdisc限制足够大,以包括模拟链路和模拟缓冲区中的数据包:
# DELAY_MS=40
# RATE_MBIT=10
# BUF_PKTS=33
# BDP_BYTES=$(echo "($DELAY_MS/1000.0)*($RATE_MBIT*1000000.0/8.0)" | bc -q -l)
# BDP_PKTS=$(echo "$BDP_BYTES/1500" | bc -q)
# LIMIT_PKTS=$(echo "$BDP_PKTS+$BUF_PKTS" | bc -q)
# tc qdisc replace dev eth0 root netem delay ${DELAY_MS}ms rate ${RATE_MBIT}Mbitlimit ${LIMIT_PKTS}
Netem 与其他 qdisc 队列合作
在某些情况下,您可能希望将netem与 disciplines 结合起来。在本例中,我们使用令牌桶过滤器(TBF)来限制输出。
# tc qdisc add dev eth0 root handle 1:0 netem delay 100ms
# tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000
# tc -s qdisc ls dev eth0
qdisc netem 1: limit 1000 delay 100.0ms
Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )
qdisc tbf 10: rate 256Kbit burst 1599b lat 26.6ms
Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )
# tc qdisc add dev eth0 root handle 1:0 netem delay 100ms
# tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000
# tc -s qdisc ls dev eth0
qdisc netem 1: limit 1000 delay 100.0ms
Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )
qdisc tbf 10: rate 256Kbit burst 1599b lat 26.6ms
Sent 0 bytes 0 pkts (dropped 0, overlimits 0 )