【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

小优有话说:

app研发不同于实验室里做研究,哪里有“理想环境”。
理想里,用户用着性能卓越的手机,连着畅通无阻的wifi网络。
“哇塞!这个app好用到飞起!”
现实是,他们可能正用着你闻所未闻的机型,穿梭于地铁、公交、火车、乡间、大山….. 信号“若隐若现,扑朔迷离”
“我去!又crash了!”
“唉,怎么又连不上网了,其他app好好的啊。”
这大概就是理想与现实之间的差距吧。

机型碎片化的问题,腾讯优测已经帮你解决了(广告就是这么硬)。
弱网络引发的crash,anr,丢包等各种问题,除了亲身到各个网络崩溃的地方测试,祈求问题重现外,还有弱网络模拟测试工具可以助你一臂之力哦!
微信测试团队的开发工程师亲身实践,为你详解弱网络模拟测试工具的那些事儿。

*

———–我是正文分割线———–

特约供稿人:微信测试团队 CoderZh

*

背景

移动互联网时代,用户会在各种网络状况下使用我们的APP。他们使用3G或4G 网络,甚至还在用2G,他们也许正在商场闲逛,也许正在地铁奔波,飞速的汽车穿过一个又一个基站,簇拥的人群挤在演唱会现场。
在弱网络下,你的APP表现还好吗?你的手游还能玩吗?
所以,我们需要一款能够模拟弱网络的软件,用来测试我们的APP在弱网络下的表现。

分析

市面上已经有一些弱网络模拟工具,比如微软的Network Emulator for Windows Toolkit(NEWT),Facebook的Augmented Traffic Control(ATC),以及WANem。

NEWT

NEWT是基于Windows的,通过图形化的界面,可以对该机器的网络参数进行设置,且模型较为丰富。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

参数设置:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

优点:
使用起来比较简单,网络模拟的参数也很丰富,模拟的准确性也比较高。

缺点:
基于 Windows。想在手机上测试时,需在 PC 上使用 USB 无线网卡建立 WIFI 热点,使用方式为独占式,且必须在 PC 上进行控制,不适用于长期开放热点供多人使用。

WANem

WANem 的实现原理基于 iptables 和 tc。它推出的年份较早,可以看出并不是针对现在的移动互联网设计的。他提供了一个可安装的 Linux 系统镜像文件,安装后可在一个网页里对该机器的网络流量进行控制。其他被测机器通过修改路由表,将网络流量引向装好 WANem 的机器从而实现对网络的模拟。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

设置页面:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

优点:
提供了安装镜像,解决了安装配置复杂的问题。

缺点:
需手工配置路由表,用户体验非常不友好,对移动端通过 WIFI 接入支持不好。

ATC

ATC 是 Facebook 开源的弱网络模拟工具,实现原理基于 iptables 和 tc。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

服务启动后,通过手机可以对网络参数进行设置:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

优点:
可多人使用,在手机端对网络参数进行设置且互不影响。

缺点:
部署起来不太方便,在 Linux 上使用 USB 无线网卡建立 WIFI 热点也是很头疼的事。当然这些都不算什么,关键是实际体验 ATC 时出现了网络模拟非常不准确的情况,比如基本的上传下载的速度控制都极为不准。在 Github 上关于这点的 Issue 非常多,最后给出的解决方案是启动 atcd 时加 –atcd-dont-drop-packets 参数,即使这样也给人留下这丫怎么那么不准的印象。

ATC 的 Web 页面在某些手机的浏览器里显示不出来,这么明显的 BUG,不知道他们现在修好了没。

网络模拟原理

NEWT 在 Windows 里进行网络模拟的原理我们不得而知,但是像 ATC 和 WANem 基于 Linux 的 iptables 和 tc 的实现原理我们倒是可以一窥究竟。

网卡

首先,有个基本的前提必须清楚,即我们只能对网卡的出口流量(egress)进行精确控制。这也比较好理解,比如我们频繁的往互联网发送数据,路由器可以轻易的控制数据往外发的速度。但如果别人频繁发送数据给你,发送速度的控制权不在你,数据来了路由器就会被动的接收,所以控制起来就会更困难。

那是不是没法对入口流量(ingress,可以理解为下载的流量)进行控制呢?其实不是的。我们只需要有两个网卡,让他们互为出口流量即可。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

其中一个网卡(eth0)接入互联网,另一个网卡(eth1)接入内网。这对应到路由器的 WAN 口和 LAN 口上。

假设在 PC 上只有一个物理网卡的情况下,也可以虚拟出一个网卡,从而实现对出口和入口流量的控制。比如我需要创建一个名为 wtc 的虚拟网卡:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

如果是正式使用,建议还是直接使用路由器的物理网卡。

通常,内网 eth1 通过 NAT 的方式将流量引入 eth0 进行上网。设置 NAT 的方式很简单,首先开启内核中的 IP 转发:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试
为了永久生效,修改 [/etc/sysctl.conf]文件,修改下行内容:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试
然后执行该命令使其生效:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试
配置 NAT 的方法:(假设 192.168.1.0/24 是你的内网 IP 段)
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试
局域网内的机器只要将网关设置成该台机器(192.168.1.1)即可通过 NAT 上网。
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

通过 vagrant,可以很容易的在一台机器上模拟出上述的网络结构用于本地调试。

流量控制

什么是流量控制?流量控制就是在路由器上通过一系列队列,对数据包进行排序以控制它们的发送顺序,并通过一系列策略控制收到的和发送的数据包是否应该被丢弃,同时还要对数据包的发送速率进行控制。

Linux 下的流量控制可以通过 tc 命令来实现的。

qdisc

首先说说调度器 qdisc,也被称为排队规则。它提供了对数据包不同的调度策略,比如最常见的 FIFO(先入先出队列)、SFQ(随机公平队列)、TBF(令牌桶),以及我们接下来需要使用的 HTB(分层令牌桶)。

HTB 的一个重要特性就是租借模型。当子分类的流量超过了 rate 时,它们就会向父分类借用令牌,直到子分类借到的令牌数量满足能让其达到 ceil 指定的速度为止,与此同时,它会暂缓发送数据包,直到有了足够多的令牌(token 或 ctoken)。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

简单理解:通过 qdisc 的 HTB 模型可以准确的对网络流量的速度进行控制。

class

qdisc 提供可分类和不可分类两种调度器。可分类的意思是,是在某个 qdisc 调度器之下,能否再分出多个子调度器。理论上,类能无限扩展,一个类可以仅包含一个排队规则,也可以包含多个各自排队规则的子类。一个类之下可以包含多个分类的排队规则。这就给 Linux 流量控制系统予以了极大的可扩展性和灵活性。

简单理解:通过 class 可以将调度器分成多个子类。

filter

过滤器是 Linux 流量控制系统中最复杂的对象,它是连接各个流量控制核心组件的纽带。过滤器最简单和最常见的用法就是对数据包进行分类。Linux 允许用户使用一个或多个过滤器将出站数据包分类并送到不同的出站队列上。

简单理解:既然前面可以分不同的 class,那流量具体要去到哪个 class,就要通过 filter 来控制了。

网络模拟

首先,qdisc 我们选用 HTB 模型,因为它可以分类,而且流量控制的比较精确。接着是 class,由于我们希望流量控制是针对具体某个 IP 的,所以每个 class 对应的是不同的用户。过滤(filter)的规则是用户的 IP 地址。

那么问题来了,如何根据用户的 IP 对流量进行分类呢?这就需要用到 iptables 的 mark 功能,通过 –set-xmark 给不同 IP 的数据打上标记,在 tc 的 filter 里可以识别这些标记,从而进入不同的分类。

不同 IP 用户的流量进入到不同分类之后,就可以针对具体的用户进行流量控制了。通过 htb 模型可以对流量进行限速,那丢包、延迟、乱序、重包等等,要怎样模拟呢?

tc 里提供了一个 netem 模块,可以对延迟(delay)、丢包(loss)、重包(duplication)、乱序(re-ordering)等进行控制,比如,给 eth0 网卡设置 100ms 的延迟:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

详尽的 netem 用法请参考:
http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

基于 IP 的网络模拟实现如下:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

如果手工执行命令的话,大概是这样的:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

实践

有了以上理论基础,熟读几遍 iptables 和 tc 的文档,实现一个基于 IP,通过手机直接设置网络参数的弱网络模拟工具就不是那么难了。

我实现了一个版本:WTC(We Traffic Control),是 ATC 更加轻量级的实现,为了把它塞进路由器里,尽量选用了体积小轻量级的框架,比如:web.py、vuejs。所有文件加起来只有几百K,已经成功在路由器(刷 openwrt)上部署。

演示:

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

为了在 openwrt 上方便部署,我制作了一个安装好 WTC 依赖环境的 ROM(基于最新的 openwrt 15.05.1),想要使用WTC,只需要以下几步:

申请一个支持刷 openwrt 的路由器。
刷配好 WTC 环境的 ROM。
做一定手工配置。

然后手机连上该 WIFI 后直接访问:http://w.tc 就可以进行网络模拟了。

当然,你也可以在你的 openwrt 环境手工配置并跑起来:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

推荐直接在路由器上搭配 lighttpd 部署, wsgi 方式运行使用 wsgi.py。

(小优注:原作者已将WTC的具体实现放置在腾讯内网,因为“你懂的”原因不方便对外公开。稍后有可能会开源哦,感兴趣的同学可以关注作者私人公众账号hacker-thinking,私下交流。
或者,大牛们看过文章可以亲自动手实践一番哦!)

*更多精彩内容欢迎关注腾讯优测的微信公众号:
【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

腾讯优测

腾讯优测是专业的移动云测试平台,为应用、游戏,H5混合应用的研发团队提*品质量检测与问题解决服务。不仅在线上平台提供「全面兼容测试」、「缺陷分析」、「云手机」等多种质量检测工具,同时在线下为VIP客户配备专家团队,提供定制化综合测试解决方案。真机实验室配备上千款手机,覆盖亿级用户,7*24小时在线运行,为各类测试工具提供支持。

【优测干货分享】微信测试工程师手把手教你做弱网络模拟测试

上一篇:微信安卓版下载 Android微信各版本列表


下一篇:微信:微信扫码支付、调用统一下单接口、网站支付 + springmvc