弱网测试--网络环境构建
按照移动特性,各种网络连接协议不同,导致通信的信号不同,速率也不同,影响app的加载时间、可用性、稳定性,因此对于应用构建弱网测试环境是必要的,弱网测试一般包括构建移动网络环境(主要是信号强弱),网络速率环境(网络延时,丢包,带宽限制,dns解析等各种复杂的网络环境),当然构建弱网环境的工具有很多,如:NistNet, netem等,本文主要介绍tc和iptables工具使用;
netem 是Linux 2.6及以上内核版本提供的一个网络模拟功能模块,该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带宽、传输延迟、丢包等等情况,其中tc是Linux 系统中的一个工具,全名为traffic control(流量控制),tc可以用来控制netem的工作模式,也就是说,如果想使用netem,需要至少两个条件,一个是内核中的netem功能被包含,另一个是要有tc。
1.tc和netmem
tc是数据包的调度者,对互联网而言,一切都是数据包,操控网络实际上是在操控数据包,操控它如何产生,路由,传输,分片等等,tc在数据包离开系统的时候进行控制,处于在IP层与网卡之间,负责将数据包传递到物理层的正是tc模块,实际上,tc维护一个先进先出的数据队列。
netem是模拟丢包,延时等功能,但是没有实现限速功能,如果要限速要使用tc的TBF。
注意:
而netem和TBF不能同时配置一条rule中,因此想要合并使用限速和丢包延时模拟,需要:
1.创建一条TBF rule模拟丢包和延时;
2.以上边的TBF rule为父节点,继续追加一条netem rule(也就是两条rule串起来);
(参考网上图的原理)tc的控制图:
(参考网上图的原理)TBF的工作原理图:
2.使用tc
常用方法:add命令是将一个节点里加入一个qdisc,remove命令是删除qdisc,change是修改规则,replace是替换等。
tc qdisc [add|change|replace|link] dev DEV [parent qdisc-id |root] [handle qdisc-id ] qdisc [qdisc specific parameters]
tc class [add|change|replace] dev DEV parent qdisc-id [classid class-id] qdisc [qdisc specific parameters]
tc filter [add|change|replace] dev DEV [parent qdisc-id|root] protocol Protocol prio Priority filtertype [filtertype specific parameters] flowid flow-id
tc [-s|-d] qdisc show [dev DEV]
tc [-s|-d] class show dev DEV
tc filter show dev DEV
(1)tc -s qdisc ls dev eth0 表示列出所有的eth0规则信息
(2)增加ping延迟命令
测试前:
PING 10.125.32.19 (10.125.32.19) 56(84) bytes of data.
64 bytes from 10.125.32.19: icmp_seq=1 ttl=50 time=3.71 ms
64 bytes from 10.125.32.19: icmp_seq=2 ttl=50 time=3.65 ms
增加延时后测试:tc qdisc add dev eth1 root netem delay 200ms
查询规则(说明已经生效): tc -s qdisc ls dev eth1
qdisc netem 8003: root refcnt 2 limit 1000 delay 200.0ms
Sent 18828 bytes 98 pkt (dropped 0, overlimits 0 requeues 0)
backlog 106b 1p requeues 0
测试结果:
PING 10.125.32.19 (10.125.32.19) 56(84) bytes of data.
64 bytes from 10.125.32.19: icmp_seq=1 ttl=50 time=203 ms
64 bytes from 10.125.32.19: icmp_seq=2 ttl=50 time=203 ms
64 bytes from 10.125.32.19: icmp_seq=3 ttl=50 time=203 ms
64 bytes from 10.125.32.19: icmp_seq=4 ttl=50 time=203 ms
当然测试完以后要删除规则:
tc qdisc del dev eth1 root
其他命令:
- 传输设置为延迟100ms±10ms
命令:tc qdisc add dev eth1 root netem delay 100ms 10ms
- 传输设置30%的包会延迟100ms±10ms发送
命令:tc qdisc add dev eth1 root netem delay 100ms 10ms 30%
(3)设置丢包
tc qdisc add dev eth1 root netem loss 50% (50%为设置的丢包率)
使用ping的测试结果:
PING 10.125.32.19 (10.125.32.19) 56(84) bytes of data.
64 bytes from 10.125.32.19: icmp_seq=3 ttl=50 time=3.65 ms
64 bytes from 10.125.32.19: icmp_seq=5 ttl=50 time=3.66 ms
64 bytes from 10.125.32.19: icmp_seq=6 ttl=50 time=3.72 ms
64 bytes from 10.125.32.19: icmp_seq=10 ttl=50 time=3.64 ms
64 bytes from 10.125.32.19: icmp_seq=11 ttl=50 time=3.65 ms
--- 10.125.32.19 ping statistics ---
11 packets transmitted, 5 received, 54% packet loss, time 10014ms
rtt min/avg/max/mdev = 3.642/3.667/3.722/0.028 ms
(4)设置包重复
tc qdisc add dev eth1 root netem duplicate 10% (10%为设置的包重复发送概率)
(5)模拟数据包损坏
tc qdisc add dev eth1 root netem corrupt 2% (2%为设置的包损坏的概率)
(7)模拟数据包乱序
tc qdisc change dev eth1 root netem delay 10ms
reorder 25% 50% (25%的数据包[50%]相关会被立即发送,其他的延迟10秒)
3.使用iptables构建入包和出包控制
(模拟只有入包和对某些入包进行过滤)
构建只要入包参数:
iptables -A OUTPUT -p tcp –sport 8080 -j DROP
使用说明 – 将原出口port的8080数据全部断掉,这样就能构建8080接口只有出包,没有入包
查看规则 :iptables -nVL –line-numbers
删除规则 :iptables -D OUTPUT 3 删除OUTPUT链上的第三条规则,就是前面设置的规则
iptables可以配置概率性丢包 : iptables -A INPUT -m statistic –mode random –probability 0.03 -j DROP
更加详细的iptables使用可以查看另外一篇博客Linux iptables 配置。
4.附录
在构建网络环境,查看包量工具的工具肯定必不可少,推荐命令和脚本:
使用iptables结合watch:watch iptables -t mangle -n -v -L
使用iptraf工具查看:iptraf
查看网卡流量脚本(每秒钟的数据):
# statics network send and recv data for every senconds
#!/bin/sh
ex_count=10
if [ $# -gt 0 ];then
ex_count=$1
fi
awk -v _count=$ex_count 'BEGIN{
OFMT="%.3f";
devf="/proc/net/dev";
print strftime("===================Start Information===================", systime());
while(("cat "devf) | getline)
{
if($0 ~ /:/ && ($10+0) > 0)
{
split($1,tarr,":");
net[tarr[1]]=$10+tarr[2];
print tarr[1],$10+tarr[2];
}
}
close(devf);
while((system("sleep 1 ")) >=0 && _count > 0)
{
print strftime("===================%Y%m%d %T===================", systime());
while( getline < devf )
{
if($0 ~ /:/ && ($10+0) > 0)
{
split($1,tarr,":");
if(tarr[1] in net)
{
print tarr[1],":",($10+tarr[2]-net[tarr[1]])*8/1024,"kb/s";
net[tarr[1]]=$10+tarr[2];
}
}
}
close(devf);
--_count;
}
}'
使用sar工具查看包量:sar -n DEV|EDEV|NFS|NFSD|SOCK|ALL 1 1 #每1秒钟取一次值
同时结合一张sar与linux网络图(参考网上)