1、背景css
如何度量和模拟“弱网络”对移动APP的开发有着重大的意义,好比:节约测试成本、易于问题重现、加快产品上线等。html
通常的方法是使用“丢包率”和“网络延时”来定义和衡量“弱网络”。web
2、手机接入服务器的流程算法
要讲这个问题,首先要来了解下手机接入服务器的流程。gulp
- 首先,手机要经过无线网络协议,从基站得到无线链路分配,才能跟网络进行通信。
- 无线网络基站、基站控制器这方面,会给手机进行信号的分配,已完成手机链接和交互。
- 得到无线链路后,会进行网络附着、加密、鉴权,核心网络会检查你是否是能够链接在这个网络上,是否开通套餐,是否是漫游等。核心网络有SGSN和GGSN,在这一步完成无线网络协议和有线以太网的协议转换。
- 再下一步,核心网络会给你进行APN选择、IP分配、启动计费。
- 再往下面,才是传统网络的步骤:DNS查询、响应,创建TCP连接,HTTP GET,RTTP RESPONSE 200 OK,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA,开始UI展示。
这是手机经过无线网络接入服务器的全过程。整个过程中有几个困扰开发者的问题:缓存
无线网络是怎么给手机分配到无线链路的?服务器
核心网络有接入点(APN),这里的CMNET和CMWAP有什么区别,仅仅是协议不一样吗吗?数据转发又有什么区别?一个数据包在不一样网络上传输有不一样吗?网络
用户怎么最快的找到正确的服务器?内容怎么快速有效的加载,在第一时间显示出来?架构
这几个问题的重点在于其中的几个链接点:并发
- 无线链路分配。这是一个物理实链接。
- IP层连接。这是一个逻辑虚链接。
- TCP层连接。这是一个逻辑虚链接。
- HTTP层连接。这是一个逻辑虚链接。
- 用户在线。这是一个逻辑虚链接。
3.2 一秒钟法则
根据以上状况,就造成无线网络的一大特色:秒级状态管理,秒级状态转换。这两个操做都在几百ms到几秒之间进行,对于维持链接来讲时间过短,对于从无链接到有链接的转换来讲时间又太长。
相比之下,有线网络的状态管理如ip分配、tcp链接释放,都是分钟级,而状态转换则是毫秒级。
这些通信机制,同时加上无线网络的高延迟、高丢包。如何保证移动互联网的产品提供稳定的、可预期的服务质量,成为很是大的挑战:
2G网络上无线部分数据传输的延迟有几百ms,4G网络上无线部分传输延迟减小到几十ms,核心网状态转换、协议转换30~100ms,IP骨干网上的延迟又跟物理距离以及运营商互联互通质量有关,跨运营商50-400ms,同运营商5-80ms,这个还要取决于网络拥塞的状况。
无线网络误码率比有线高两个数量级,在不一样时间段的波动也很是巨大。
怎么基于移动网络的特性去优化服务?
这就是咱们总结的一秒钟法则:在一秒内要完成的规定动做。
- 2g网络:1秒内完成dns查询、和后台服务器创建链接
- 3g网络:1秒内完成首字显示(首字时间)
- wifi网络:1秒内完成首屏显示(首屏时间)
- 这些指标须要在终端度量,必须跟用户体验相关:首字时间、首屏时间都必须是用户能够直观感觉到的。
4、优化思路
4.1 服务保证原则
从以上分析可知,如何保证移动互联网的产品提供稳定的、可预期的服务质量,具备很是大的挑战。如下几点原则可能会有帮助:
- 接口设计优化,接口的优化理论上不属于APP弱网络的优化,可是这个的API性能的问题,确实在网络条件很差的状况下才暴露无遗。你们都在谈论服务器的好坏,设备的性能高低,其实,对于一个良好的Server来讲,绝大部分拖延请求速度的地方都是在IO上。包括,磁盘读写的IO,SQL查询的IO等等。经常使用的优化点:慢查询监控 、屡次查询优化、经常使用接口cache等。
- 图片相关策略。
- 使用更快的图片格式,严格说也不算弱网下的优化,但一个更快的图片格式真的很重要!这里建议采用WebP格式。(WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。但WebP是一种有损压缩。相较编码JPEG文件,编码一样质量的WebP文件须要占用更多的计算资源。)
- 不一样网络的不一样图片下发。如(对于原图是600X480的图片):2/3G使用低清晰度图片——>下发300X240,精度为80的图片、4G普通清晰度图片——>下发600X480,精度为80的图片、WiFi高清晰度图片(最好根据网速来判断,wifi也有慢的)——>下发600X480,精度为100的图片。
- 断线重连。这多是最重的一个特性,由于在无线网络中有太多的缘由致使数据链接中断了。这里可使用CDN。(CDN 是构建在数据网络上的一种分布式的内容分发网。 CDN 的做用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提高系统支持的并发流数目,减小或避免单点失效带来的不良影响。)
- 因为建立链接是一个很是昂贵的操做,因此应尽可能减小数据链接的建立次数,且在一次请求中应尽可能以批量的方式执行任务。若是屡次发送小数据包,应该尽可能保证在2秒之内发送出去。在短期内访问不一样服务器时,尽量地复用无线链接。
- 优化DNS查询。应尽可能减小DNS查询、避免域名劫持、DNS污染,同时把用户调度到“最优接入点”。
- 减少数据包大小和优化包量。经过压缩、精简包头、消息合并等方式,来减少数据包大小和包量。
- 控制数据包大小不超过1500,避免分片。包括逻辑链路控制(Logic Link Control)分片、GGSN分片,以及IP分片。其中,当数据包大小超出GGSN所容许的最大大小时,GGSN的处理方式有如下三种:分片、丢弃和拒绝。
- 优化TCP socket参数,包括:是否关闭快速回收、初始RTO、初始拥塞窗口、socket缓存大小、Delay-ACK、Selective-ACK、TCP_CORK、拥塞算法(westwood/TLP/cubic)等。作这件事情的意义在于:因为2G/3G/4G/WIFI/公司内网等接入网络的QoS差别很大,因此不一样网络下为了取得较好的服务质量,上述参数的取值差别可能会很大。
- 优化ACK包。在弱网络的状况下,TCP协议中的ACK包是很是昂贵的,延时甚至可以达到秒级别,而TCP协议的拥塞控制、快速重传、快速恢复等特性都很是依赖接收端反馈的ACK包。可想而知,若是发送端接收到的ACK包延时太长,会严重影响TCP协议的效率。可是若是发送ACK太多又会占用宝贵过多的无线资源。在移动网络下通讯,“在可靠的链接上,如何在减小ACK包的状况下,下降数据包的延时”是研究的热点。基本的思想:平衡冗余包和ACK包个数,达到下降延时,提升吞吐量的目的。例如SGSN和GGSN之间的通讯实现:两者之间经过UDP协议通讯,发送者在无新的数据包的状况下,每隔必定的时间重试已发送的包,达到最大重试次数后,则丢弃该包。
- TCP的拥塞控制算法是以“丢包意味着网络出现拥塞”为假设设计的,很明显这个假设在无线网络环境下是不合适的。可是在无线网络环境下,在设计可靠UDP协议时是否可以彻底丢弃拥塞控制呢?这里有其它的文章中提出了几种在无线网络环境下的TCP友好的拥塞控制算法,有兴趣能够自行查阅。
- 灵活使用长链接/短链接,支持不一样协议(TCP/UDP, http、二进制协议等),支持不一样端口等。
- 让用户以为快。到这里已经不能算是技术层面的方法了,属于一种心理层面的博弈,一种改善用户体验的方式。好比:
- 不从0开始的进度条。无论网页的加载进度如何,无论网络条件如何,加载进度始终是从50%起,而且停留在大约98%进度左右的地方。
- 先显示文字在加载图片。一样是在Webview之中,图片或者多媒体的加载速度确定是远远慢过文字的加载速度的。因为不一样的webview显示和渲染效果不一样,咱们能够先让webview先显示文字,在显示图片。给用户一种能够先预览整个网页概况的感受。
4.2 接入调度优化
接入调度优化首先要考虑的是减小DNS的影响。移动网络的DNS有以下特色:
- 骨干网没法识别移动用户在哪一个城市,东西南北各个地方的调度没有充分调用。目前有一部分全国范围的DNS承载了超过40%的全网用户
- 不少山寨机的终端local dns设置是错误的
- 另外还有一些有线网络也同样会遇到的问题,如终端DNS解析滥用、域名劫持、DNS污染、老化、脆弱等。不过对于这些问题,桌面的自愈性会比较好,而在手机上则比较难以解决。
对于DNS的问题,有两条主要的解决思路:
- 减小DNS的请求、查询、更新,也就是作DNS缓存
- 在终端配置server list,直接访问IP,不用DNS
但仅仅这么作还不够,由于用户可能来自国内外不一样的运营商,还须要进一步优化调度策略:
- DNS缓存须要多创建接入点,用不一样域名区分
- IP列表须要更新以适应不一样网络状况,要作到主动调度。比如最先咱们只服务好移动用户就行,保证移动用户的接入质量优先,由于绝大多数用户集中在移动;如今国内有三个运营商,用户分布的比例在慢慢接近,要区分清楚;智能手机会用wifi,接入的是电信、联通仍是哪一个运营商,不知道,因此你不可能预先设置场景再if then,必须经过后台调度能力来解决。
再进一步优化,就产生一种融合的方式:
- 先作域名解析,客户端直接链接解析的IP,能够用http协议,也能够用tcp socket
- 多端口、多协议组合:不一样协议有不一样的限制,有些只能http,有些只能tcp socket,各类环境都要适应,客户端不能只支持一种协议
- 终端测速:接入点愈来愈多,接入哪一个合适,要选择,能够经过终端测速来选择最快的。你固然能够每一次新建链接都作测速,可是这样创建链接时间可能会很长;咱们能够给用户先创建链接后,在后台根据长期速度监控、当前测速的结果,来作动态调度。也就是说,第一次链接可能不是最优,链接创建后动态测速,再转移到最快接入点。更进一步就是创建网络profile,终端学习的思路。
关于测速采样的粒度,移动互联网取IP段是没用的,比较好的粒度是到网元级别,好比广东有20多个wap网关,每个网关的状况都不同,这就是一个比较合适的粒度。
最后强调一个全部的接入调度原则:不要把调度逻辑写死在客户端,必定要由后台完成。
4.3 协议优化
协议参数优化这块就简单列一下,是长期运营过程当中总结的一些经验,在启动移动互联网服务时做为运营的规范,能够少走不少弯路:
- 关闭TCP快速回收
- Init RTO不低于3秒
- 初始拥塞控制窗口不小于10。由于大部分页面在10kB如下,不少请求在慢启动阶段已经结束,改成10能够下降小页面资源传输时延。内容越大,这个选项的效果就比较不明显。
- Socket buffer > 64k
- TCP滑动窗口可变
- 控制发包大小在1400字节如下,避免分片
协议优化的原则总结下来是这么几条:
- 链接重用
- 并发链接控制
- 超时控制
- 包头精简
- 内容压缩
- 选择更高效率的协议。不管是TCP、HTTP、UDP、长链接、GZIP、SPDY、WUP仍是WebP,每一种协议、方案都有其道理,没有最优,只有是否适合你的产品和服务特色,须要你们在运营过程验证和取舍。
4.4 WAP接入点优化
关于WAP接入点优化,可能有些人会说,咱们的App是高端大气上档次的应用,是否是就不用作WAP优化?实际上咱们的统计显示,目前有5%-20%的用户选择的接入点是*WAP(CMWAP、3GWAP、CTWAP),这甚至包括一些iPhone终端。实际上,WAP网关本质是个代理,不彻底是落后的东西,随着技术的进步也在演进,之后在组网架构中可能有综合网关、内容计费网关来取代目前的WAP网关,因此建议也要一并考虑。如下是作WAP优化须要注意的一些问题:
- 资费提醒页面
- 302跳转处理
- X-Online-Host使用与处理
- 包大小限制
- 劫持与缓存
- 正确获取资源包大小
4.5 业务逻辑优化
一、简化逻辑:交互繁琐的内容尽可能用标识更新。举一个例子,咱们在老版的手机QQ上作过一个测试:假如我有100个好友,用手机QQ完成登录,完成好友列表更新一遍,须要3.5分钟。这确定是不合理的。建议用信令状态来通知是否须要更新,同时合理利用缓存。在好比玩游戏,好友给你送了不少星星,是让用户一次一次点仍是批量点?从优化的角度确定是批量点,从用户体验的角度这也更加舒服。
另外一方面,延长域名图标的缓存时间也能够有效地优化访问次数。咱们把手机腾讯网图标的缓存时长从120分钟延长到2天后,访问次数优化了差很少35%。
二、柔性可用:这个意思就是在网络质量好的时候给高清大图,很差的时候先给用户看小图,点一下再拉取原图。举一个极端的例子,好比万一地震了,基站毁掉20%,用户要给家人报平安,这时候产品上就必须优化,好比只发送文字,合理降3,低网络消耗。另外在响应很慢的时候,须要给用户一些合理的页面提示,好比提示用户再过5秒会发送,因此你不要一直刷屏,这也能够减小访问对后台服务、对网络的冲击。
五 实战演示
5.1 一个最优调度设计示例
上面说了那么多,这里就给出一个实例帮助你们更直观的理解。
这里给出一个DNS系统设计来实现最优调度。其拓扑结构以下:
TGCP SDK的职责:
- 用HTTP的Get/Post方法从DNSvr获服务器和DNSvr自己的最优接入点列表。Get/Post方法的查询参数包括uin/openid、客户端版本号、IP列表的MD5(注意IP顺序)、域名列表、VIP、ServiceID等。
- 缓存访问服务器和DNSvr的IP列表,以及其它元数据(好比IP列表等),且以APN为主键。
- 知足必定的条件下,要主动更新缓存的IP列表,例如缓存过时。
Tconnd的职责:
- 路由查询请求给活动的DNSvr;
DNSvr的职责:
- 根据静态和动态策略来决定客户端的“最优接入点”。静态策略:根据uin/openid、客户端版本号或者强制规则来决定IP列表;动态策略:灯塔根据测速数据动态决定用户的服务器接入点。
- 支持以手动或自动的方式拉黑某些IP。自动方式:由服务器的接入tconnd向DNSvr上报其是否存活(须要向多个点上报,包括用公网IP上报),若是在必定时间内没有接收到上报或者上报消息中明确全部的逻辑服务器已经挂掉,则自动拉黑相应的IP。若是业务恢复,则自动激活相应的IP。若是项目组接入TGW,对于某个IP和端口是否可用,则须要考虑进程与VIP的映射关系。
- 在tcaplus中缓存灯塔的计算结果。此时要求DNSvr可以根据客户端IP判断所属的国家、省份、运营商和网关(能够经过访问MIG的IP库实现)。若是缓存了灯塔的计算结果,当缓存超时后,要从新从灯塔拉取相应数据。
灯塔的职责:
- 根据客户端IP和服务器接入点IP,返回最优的接入点列表,包括IP的排序,以及客户端接入的国家、省份、运营商、APN和网关。
Tcaplus的职责:
- 保存接入的IP列表和端口、静态策略,或缓存灯塔的计算结果;
主要的流程:
客户端批量解析域名流程
- TGCP以APN和域名列表为关键字查询缓存,若是存在且没有过时,则直接把IP返回给用户。若是指定强制解析域名列表,则跳过此步骤;
- TGCP用预配置或缓存的IP向DNSvr发起查询请求,若是成功返回结果,则执行步骤3,不然,重试IP列表中的其它IP,若是都失败,则用域名访问DNSvr。注意:若是是结果格式不正确,则使用上次的IP重试,不要更换IP重试。
- DNSvr比较客户端IP列表和当前最新的IP列表的MD5,若是相等,则告诉客户端不须要更新本地缓存。不然,TGCP把接入服务器和DNSvr的IP列表写入本地。注意:在访问服务器时,这些IP的优先级要高于静态配置在客户端的IP。
客户端使用域名访问服务器流程
- 若是本地存在有效的IP(即存在对应APN的IP列表,且没有失效),则使用IP访问服务器。
- 不然,发起“客户端批量解析域名流程”后,再访问服务器。
服务器接入tconnd主动上报状态流程:
- Tconnd周期性向DNSvr上报心跳消息,其中包含本接入点是否可用的信息。
- DNSvr在必定的时间内没有收到心跳消息或者相应的接入点不可用,则把相应的IP和端口拉黑,黑掉的IP不在下发给客户端。
注意:实际部署的时候,接入的Tconnd要向多个DNSvr接入tconnd上报。
向客户端主动push接入点列表的流程
- 当TGCP链接到服务器接入的Tconnd时,Tconnd要向DNSvr发起请求,以校验当前接入IP的质量和时效性。若是IP列表发生变化,Tconnd要把最新的IP列表下发给客户端缓存起来。
- 当TGCP下次访问服务器时,则使用最新的IP列表。
客户端访问DNSvr失败的流程
- 若是访问DNSvr失败(包括IP+域名),若是配置了本地IP,则直接用IP访问服务器,不然用域名访问。
优化传输层协议设计
在原有tconnd支持的可靠UDP的基础之上,添加如下逻辑:
- 数据压缩;
- 数据加密;
- 合并多个数据包;
- 支持流式数据传输,便于控制每一个UDP包的大小,也便于数据加密和压缩;
- 可选地支持改进的拥塞控制算法;
- 即便没有接收到ACK包,也须要主动重试以发送的数据包;
5.2 Hybird开发下的一些优化
要处理在弱网络下的加载速度,那么咱们要先肯定一下咱们的整个APP在哪一个地方加载的速度如何,最长的加载路径在哪里,咱们从而才有针对性的进行优化与修改。
5.2.1 WebView
若是是对是APP中内嵌的webview网页,针对网页体验优化已经由来已久了。咱们可使用Chrome的开发者模式,调整到Network模式下,将网络条件设置为3G去请求网页,那么咱们就可以看出来一个网页加载的速度主要都耗费在哪一个地方,以下图所示:
固然,html的加速方式有不少种
- 使用gulpgrunt进行打包压缩:jscss资源压缩,CSS Sprites合并等。
- 使用font-awesome替换图片:字体能够很好的兼容,无限放大,经常使用的图片都有
做者:cosWriter 连接:https://www.jianshu.com/p/f7600907d355 来源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。