在解决日常的支持需求中,经常会遇到一些用户反馈一些无法简单复现的bug,有很大一部分的bug是由于用户自身的网络环境波动,或者是本身网络环境就较为恶劣,而服务在面对这种恶劣的网络环境的健壮性不够,导致会出现一些意想不到的bug。而在正常的开发自测过程中很难去营造出这种恶劣的网络环境,使得这些bug较难被提前发现和修复。另外一些服务在恶劣网络环境下虽然不会出现不可用的情况,但是用户体检很差,为了优化这个情况下的用户体验,也需要去在本地模拟这种环境来进行调优。
所以要去复现这些bug,甚至是去提前发现这些bug,就需要能够在开发环境中模拟出恶劣的网络环境,从而看到在这种恶劣的网络环境下的服务的表现等。当前模拟恶劣网络环境主要可以通过以下这些手段实现:
- 通过应用层或者传输层的代理服务器,通过在代理服务器上设置一些模拟恶劣网络环境的参数,使得通过这些代理服务器的流量都被转化为恶劣网络环境下的流量。如利用Fiddler,Charles等具有代理服务器功能的网络流量分析软件来实现。
- 通过利用一些更底层的驱动层面的服务,通过控制网卡的收包发包的行为,来模拟恶劣的网络环境。如dummynet的ipfw驱动等。
- 通过建立一个可控的网关,在网关上部署模拟恶劣环境的相关程序,所有需要借助该网关进行转发的流量都会被模拟为恶劣网络条件。Linux下的netem就提供了这类支持。
这里主要先讲的是第一种手段,即利用Fiddler来模拟恶劣的网络环境,对服务进行测试,这个手段实现简单,较为直观,但是缺点是只能支持那些利用HTTP进行通信和交互的服务。在之后的文章中也会进一步说一下后两种手段。
一、利用Fiddler模拟恶劣网络环境
【简单地利用Fiddler限速模拟恶劣网络环境】
Fiddler本身已经预置提供了模拟Modem速度的选项,其位置位于:
Rules – Performances – Simulate Modem Speeds
勾选该选项后,所有通过Fiddler代理的流量都会变得和多年前的56k小猫时上网一般的慢。
由于Fiddler只是一个HTTP代理,要直观地看出限速效果,最好是运行在浏览器中的测速工具,这里选用speedtest.net提供的测速工具进行测试。
首先是开启该选项之前的速度:
打开了Simulate Modem Speeds后:
速度已经回到了当年那种无法忍受的低速了,注意到这里PING值也有了显著的提高,而事实上ping值是ICMP层的控制报文,并不会被Fiddler影响,理论上ping值并不会出现提高的情况,进一步分析Fiddler中的报文则可以看出端倪:
事实上网页插件并不能实现发送ICMP包并得到ping值的功能,而是用多次较小的HTTP GET请求的响应时间来计算PING值,这里实际算出来的是一个平均的HTTP的RTT值,所以受到Fiddler模拟恶劣环境的影响就是正常的了。
【调整模拟恶劣网络环境的参数】
直接模拟Modem速度实在是慢爆了,事实上就算是在很差信号的情况下,手机移动网络的速度都已经超过了当年的56k Modem速度了,所以采用默认的配置模拟出来的环境过于恶劣,并不一定符合需求,此时就需要对限速的参数进行调整。
Fiddler本身就提供了一个配置文件供调整这些参数,点击:
Rules – Customize Rules…
就会用文本编辑器打开CustomRules.js文件,其默认位于用户目录的文档目录下的\Fiddler2\Scripts 位置,后缀名是js,其内容实质是JScript.NET——微软对ECMAScript规范的实现,与日常使用的javascript是属于同一个规范下的,但是在扩展的细节实现存在一定的不同。
打开该文件后,可以找到一个m_SimulateModem标志位:
if (m_SimulateModem) {
// Delay sends by 300ms per KB uploaded.
oSession["request-trickle-delay"] = "300";
// Delay receives by 150ms per KB downloaded.
oSession["response-trickle-delay"] = "150"
}
- 该标志位控制着oSession的两个参数值的设置,当勾选了Simulate Modem Speeds时,request-trickle-delay与response-trickle-delay就会被设置,其中request-trickle-delay中的值代表每KB的数据被上传时会被延时多少毫秒,response-trickle-delay则对应下载时每KB的数据会被延时多少毫秒,如果本身网速已经相当快的话,这里设置的值就可以近似地推算出开启模拟后的上传和下载带宽了,比如默认设置下下载延时为150ms,上传延时为300ms,对应可以推算出大致的模拟带宽为:
然而实际情况下却得到了两倍于这个值的带宽,推测可能是Fiddler的内部实现上有一些和描述上的不同,为何为造成这个现象现在还不是很清楚,所以上述公式最后还需要修正一个2.0的系数,即:
假设我们将两个参数都设置为50,则会得到上下载带宽均为0.32Mbps,测速结果如下所示:
【编写自定义脚本】
进一步地,我们可以扩展CustomRules.js里的逻辑,参照Jscript的文档可以在模拟恶劣环境中加入更多自定义的逻辑,这里实现了一个随机延时量设置,使得网络带宽不是恒定为一个低速的值,而是会在一定范围内随机抖动:
static function randInt(min, max) {
return Math.round(Math.random()*(max-min)+min);
}
if (m_SimulateModem) {
// Delay sends by 300ms per KB uploaded.
oSession["request-trickle-delay"] = ""+randInt(1,50);
// Delay receives by 150ms per KB downloaded.
oSession["response-trickle-delay"] = ""+randInt(1,50);
}
得到的测试结果如下:
在测速过程中的瞬时速度的趋势图如下:
可以看到整体的网络限速存在了一定程度的抖动。
通过进一步扩展CustionRules.js可以实现很多需要的恶劣环境模拟场景,如果场景较为复杂的话,也可以通过编写Fiddler的插件的方式,编写C#插件代码来进一步控制Fiddler的行为,在这里就不多做赘述了。详细可以参照:http://docs.telerik.com/fiddler/extend-fiddler/extendwithdotnet
【Fiddler模拟恶劣网络环境的局限性】
Fiddler进行限速较为简单和灵活,配置也较为方便,但是由于它是一个应用层的HTTP的代理,只能模拟该层上的行为,对于一些复杂的网络层的丢包、重传等恶劣情况就不能很好的模拟出来,而且对于其他协议的应用也不支持,后续会介绍一些其他的模拟恶劣环境的方法和软件来弥补这些缺失。
二、QNET使用
[什么是Qnet]
QNET腾讯WeTest开放平台最近推出了一款针对移动应用的弱网测试工具QNET,解决了在Android设备上进行弱网络专项测试的痛点,QNET无需ROOT手机,无需连接数据线,以独立app的方式,为用户提供给快捷、可靠、功能完善的弱网络模拟服务。
另外QNET还有一个很好用的功能——TCP/UDP网络协议抓包,帮助开发和测试人员进行网络流量分析,而不需要ROOT手机,使用tcpdump进行抓包。
QNET网络测试工具能够不借助PC或服务器,搭建一套完整的弱网测试环境,进行弱网络模拟测试,秩序在任意只能手机上安装QNET网络测试工具,即完成弱网络测试环境搭建工作,接下来根据需要选择不同场景进行测试即可,除此之外,还提供了网络数据包抓包功能,便于进行网络数据问题的分析。
【Qnet如何使用?】
1、登录
下载安装好Qnet app后,进入Qnet,可使用QQ登录。
2、选择要进行测试的应用
3、选择好要进行测试的应用后,界面会有提示让你前往网络场景添加模板数据,点击界面下方的【网络场景】进入到网络场景推荐页面
4、【网络场景】界面会有很多常用的网络场景,选择所需要的场景点击【添加】按钮,会进入到所选网络场景的各个参数的详细数据设置界面,会有各个参数的默认数据,可以根据实际情况修改对应参数数值(包括网络带宽、网络延时、延时抖动、随机丢包、周期弱网、协议控制等)。
5、参数修改好之后,点击右上角的【保存】按钮,该网络场景就会保存并显示在【工作台】界面。
6、点击场景名称→点击【启动】
(注:首次启动会提示“授权Qnet的悬浮窗权限”,点击ok后,跳转到悬浮窗管理界面,将Qnet的悬浮窗权限打开)
7、回到Qnet后,点击【启动】按钮,会弹出“是否允许Qnet创建VPN连接”弹窗,点击【始终允许】即可。
8、启动后就会直接进入所选择的应用,界面就会显示网络环境的数据的悬浮窗,可以随时选择暂停或开始,右侧会实时显示网络环境数据。(点击左侧的倒三角可以切换网络环境)
9、点击右上角的【新增】也可以自定义网络环境模板,可以模拟不同的地区、不同的运营商、不同的网络场景。
10、支持TCP/UDP/ICMP协议网络抓包,在设置中将【网络抓包】开启,然后重启qnet即可,抓好的包以pcap文件格式保存,文件自动存在手机的/storage/emulated/0/qnet_save/pcap路径下,可以用wireshark在pc端打开进行数据分析。
wireshark下载地址:https://www.wireshark.org/download.html
【自定义模板参数介绍】
(1)网络带宽
单位kbps,限制当前网络上下行最大的带宽容量,例如针对腾讯视频设置1024kbps限速后,下载速度 只能达到128KB/s左右:
(2)网络延时
单位ms,当前网络的上下行延时约等于设置值,设置延时100ms,200ms,300ms
(3)延时抖动
对每个数据包以设置的概率进行抖动选择,延时范围在0~抖动值之间随时产生
(4)随机丢包
按设置的概率对每个包进行丢包
(5)周期弱网:
按照放行时长、弱网时长设置交替切换,根据弱网类型进行弱网。
弱网类型:
【完全丢包】:处于弱网时长的数据包直接丢包
【Burst】:模拟路由或者底层硬件在判断当前网络连接不通时保存数据包,在网络通畅后爆发式的将 数据包推送出去,
(6)协议控制
支持对不同协议的弱网控制,协议类型包括TCP\UDP\ICMP\DNS;
(7)IP控制 可以针对IP进行弱网控制,多个IP以|分割。
【场景模板介绍】
(1)网络选择
提供真实的省市间网络传递的数据参数、运营商数据、网络类型数据;
(2)场景选择
提供多个真实测量不同场景下的网络波形
【术语】
1、衡量网络好坏的标准
(1)带宽(吞吐量):单位时间内传输的数据量(bps),反映网络的传输能力
(2)丢包:数据丢包个数=发送的数据包数-接受的数据包数,反映为网络的可靠性
(3)时延:数据包从发送开始到接受到该数据所耗费的时间,反映网络速度
(4)抖动:指时延的变化,反映网络的稳定性
(5)乱序:指接受到的数据包顺序和发送顺序不一致的次数,反映网络稳定性。乱序比较 严重时,丢包也会比较严重,所以一般以丢包为主
2、术语
(1)上/下行带宽(kbps—千比特每秒)
上行带宽(上行速率):本地信息上传到网络的速率
下行带宽(下行速率):网络信息下载的本地的速率
注:上行速率不等于下行速率,在大多数情况下,下行与上行带宽的比率可达到10:1
(2)上/下行丢包率(%)
数据在网络上是以数据包未单位传输的,由于一些原因不能百分百得完成,这时网络会自动根据协议来补办,网速快线路好得时候,包得损失会非常小,补包就会很容易完成,但是线路较差得时候,数据得损失量就会很大,补包就不可能百分之百完成,这种情况下就会造成丢包。
丢包率 = 1 - 单位时间内接收得数据包数 / 发送的数据包数
查看丢包率可以通过ping命令来查看
(3)上/下行延迟(ms)
1-30ms:极快,几乎察觉不出有延迟
31-50ms:良好,没有明显的延迟情况
52-100ms:普通,能感觉出网络有明显延迟
大于100ms:差,有卡顿,丢包并掉线现象
(4)DNS延迟(ms)
DNS是域名解析服务器,延迟就是和这个服务器的连接速度,DNS的作用就是把网址解析成IP地址,因为电脑网络连接只能通过IP连接。