网络性能指标:
1.建立连接的速度 2.传输速度 3.到达率(TCP/IP底层已经有错误重传机制,但是并不是专门为移动端设计的)4.长连接的存活率
优化切入口:
1.DNS优化(一般是优化的首选),使用HTTPDNS替代LocalDNS
DNS是指根据域名查出IP地址,是HTTP协议的前提,所以网络优化的第一步就是DNS优化。
DNS优化主要体现在两点:1.安全性:减少或避免由于DNS劫持造成服务不可用。2.速度:解决由于DNS调度不准确影响网络性能(1.DNS调度不准确2.运营商如果修改DNS的TTL会导致DNS修改生效延时,不同运营商实现细节不同,难以保证DNS解析的耗时)
HTTPDNS:大部分标准DNS都是基于UDP与DNS服务器交互的,HTTPDNS则是利用HTTP协议与DNS服务器交互,绕开了运营商的Local DNS服务,有效防止了域名劫持,提高域名解析效率,下图是HTTPDNS的原理。
2.连接重用,避免重复握手:
HTTP1.1的Keep-Alive。
如果之前已经连接过,会尽量重用之前的连接(15S好像)(不一定满足所有场景,国内比较乐观,国外)
客户端拥塞算法与服务端延时算法(服务端维护一个拥塞队列等待客户端ACK)冲突
解决方法:截包,看是不是每个请求都延时一定时间,如果有这种情况,可以选择关闭TCP delay的开关(发送方)
缺点:H1连接复用需要网络请求的域名和端口号一致,复用率有限。keep-alive必须等当前请求完全结束才能发起下一次请求,无法并发。
HTTP2.0的多路复用。
进一步提升复用率,支持一条连接同时处理多个请求,H2支持同一域名的复用。
缺点:1.一条连接只支持同一域名
2.后端支持H2需要额外的改造
3.同一域名只保留一条连接,所有请求都集中在一条连接,网络拥塞的时候会出现TCP队首阻塞。对于像视频播放,文件下载这样的场景,可能会遭到服务器单条连接的限速
针对H2的这些缺点,我们有如下应对措施:
1.不改造后端实现H2:在统一接入层做改造,统一接入层实现将数据转换到H1再由H1转发到域名对应服务器。
如图:
2.针对视频播放,文件下载这样的场景,遭到服务器单条连接的限速时。我们可以通过修改网络库,也可以简单地禁用H2协议来解决。
3.压缩与加密
上面是连接过程的优化,接下来是发送与接收的优化。
发送与接收的优化可以通过减少传输的数据量实现。也就是数据压缩
HTTP请求的数据包括三部分:URL,请求header,请求body。
1.如果我们的协议采用是HTTP/2,那么数据本身就是支持头部压缩技术,所以压缩主要体现在URL和body的压缩。
2.URL一般会携带很多参数,其中大部分参数是不变的,这些不变的参数只需上传一次即可,其他请求可以在接入层进行扩展
3.请求body,网络传输中最流行的两种数据序列化方式:JSON和Protocol Buffers。Protocol Buffers使用起来会比较复杂(需考虑使用成本),但是在压缩率和序列化反序列化的效率上都远胜JSON
数据压缩还可以通过压缩算法实现,比如Gzip,Google的Brotli和FaceBook的Z-standard等。其中,最常见的是Gzip。
经典问题:1.优化与优化碰一起的错误。
客户端:防止拥塞的算法,把所有小请求压缩到一起,一次发过去,这样的好处是可以避免每一个小请求都有请求头。
服务端:延迟确认算法,维持一个队列,客户端的请求不一定会马上执行,会把他hold住,等下一次请求过来在一起回来,这样减少一次回执时间,提供网络利用率
但是两个一起用,两边都会在等对方的下一个请求,所有请求延迟40ms或者200ms。这是一个很经典的问题。
如何处理,截包,看是否每个请求都是固定的delay,如果有,关闭tcp delay的开关。
Rfc1122规定迭代时间不超过500ms就可以
Nagle算法规定同一时间只能有一个队列在堵住请求,客户服务端不能同时有拥堵队列
2.慢启动,防止拥塞:
TCP能发送的包有限,不要在一开始把所有请求在开机一开始全部做了。
网络优化的手段是需要应变的,没有万金油的。
内容内嵌,把图片(小图不超过2 3K)变成base64,直接decode一个二进制的流(比如请求微博,头像这种小图,可以在json里面直接搞,一次请求获得大量信息,以后直接用)。比如,减少请求次数,图片不要在后台去加载
HTTPS可以防止DNS劫持,HTTPS加密本身并不会加大多少开销,但是换了HTTPS之后你还是会觉得有卡顿。最影响性能的是HTTPS的证书链。1.确认证书链上每个证书不是废弃状态,可信任状态(而且DNS服务器很难去优化)
2.中间证书的颁发机构如果比较小(便宜),可能延迟很久。用钱可以解决。而OKHTTP3.0以上,证书这一块已经做好了接口,添加域名和sha就可以,不过有一定安全性问题。
如果想跳过DNS,可以选择IP直连。Mars在这一块有好些网络优化策略
OkHttp的最新版本3.10.0,2018年2月25日发布,特性如下:
Gzip可通过拦截器实现
HTTP2在RealConnection中,就默认会查询服务器是否支持,支持就开启
HTTP2.0优化:
优点:
1)采用二进制格式传输数据,而非http1.1文本格式,二进制格式在协议的解析和优化扩展上带来了跟多的优势和可能
2)多路复用,相同host的请求可以共用一个socket连接
3)压缩头信息(对消息头采用Hpack进行压缩传输,能够节省消息头占用的网络流量,
http1.1每次请求,都会携带大量冗余的头信息,浪费了很多宽带资源)
4)请求划分优先级
5)支持服务器端主动推送
6)保持与HTTP 1.1语义的向后兼容
长连接心跳的意义:不仅是告诉服务端连接还在 防止NAT超时才是主要的
确认网络状态
错误重传:TCP指数推币,get请求可以随意重传,可能修改数据的请求(post,delect)要谨慎重试
短连接:HTTP请求数据是报文(类似字符串一样的东西) 长连接:二进制流