Android开发技术周报176学习记录
教程
当 OkHttp 遇上 Http 2.0
http://fucknmb.com/2018/04/16/%E5%BD%93OkHttp%E9%81%87%E4%B8%8AHttp-2-0/
记录
问题:App上的菊花一直在转消失不掉。
原因:okhttp3.4.1在http2.0下使用了被关闭的连接,导致出现无限循环。在http code!=200时,重连,没有结束死循环导致的。
解决:在http code!=200时流为关闭的情况下,连接意外中断触发了这个死循环,避免文件的简单有效的途径是http code不论多少,直接关闭。
Android客户端网络性能调优之HTTP/2协议升级
https://mp.weixin.qq.com/s/N16jX2zRT3mlaJF4ixDhMg
记录
HTTP/2与HTTP/1.X的区别
- 二进制分帧
在应用层与传输层之间增加一个二进制分帧层,以此达到在不改动HTTP的语义、HTTP方法、状态码、URI及首部字段的情况下,突破HTTP1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。
在二进制分帧层上,HTTP2.0会将所有传输的信息分割为更小的信息和帧,并对它们采用二进制格式的编码。 - 压缩头部
HTTP/1.X的header由于cookie和user agent很容易膨胀,而且每次都要重复发送。
http2.0使用HPACK算法压缩来减少需要传输的header大小,通讯双方各自缓存一份header fields表,既避免了重复header的传输,又减小了需要传输的包数量,从而降低了延迟。 - 多路复用
客户端和服务端可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。
在一条连接上,可以同时发送无数个请求,并且响应可以同时返回。
Android客户端基于HTTP/2协议之上的优化
-
兼容HttpDns方案
客户端统一接口和图片的HTTP/2网络请求适配了自研HttpDns服务,避免了运营商LocalDNS解析劫持,提高了用户解析成功率,同时也加快了服务器解析切换的生效时间,减少了故障影响范围。
Android原生网络接口HttpUrlConnection不支持HTTP/2协议,客户端网络模块可以继承Square公司开源的网络组件OkHttp,OkHttp组建原生支持HTTP/2协议,然而在兼容HttpDns服务时,需要解决如下几个问题:
(1)URL中host替换为HttpDns的IP后HTTP/2协议转换:authority字段修正
HTTP/2协议RFC文档中采用:authority字段代替HTTP/1.X Header中Host字段,Okhttp未在V3.6.0版本之前做两个字段之间的转换,导致nginx服务器取不到正确的authority字段,无法实现请求转发。
网络模块接入HttpDns将请求URL中的Host字段替换为HttpDns下的IP,然后在Header中增加Host字段,这样可以保证后台nginx服务器能正确转发请求。
(2)URL中host替换为HttpDns的IP后SSL/TLS握手初期SNI字段修正
SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。工作原理就是在连接到服务器建立SSL/TLS连接之前先发送要访问站点的域名(Hostname),这样服务器根据这个域名返回一个合适的证书。
由于SNI的传递过程是基于传输层(TCP)层,所以如果基于HTTP协议层的Header字段带Host是不能生效的,这里对Okhttp的Sni传递流程做了改造,将Sni参数从应用层透传到传输层,从而解决了Sni从现有URL中解析出来为服务端无法识别的问题。
(3)HTTP/2长连接简历握手过程中网络域名校验问题修正
域名校验是Https握手过程中验证证书有效性的重要环节,目的是为了验证服务端下证书颁发机构的合法性,如果简单忽略掉域名校验,将会给中间人可乘之机。
Okhttp的握手过程Host是从URL中解析出的,如果URL中的Host被HostDns的IP地址替换,Https握手校验过程将会失败,这里也是通过对OKhttp传输层握手过程进行改造,透传了正确的Host字段,适配了HttpDns IP直连这种场景。 -
客户端HTTP/2长连接管理优化
问题:应用长期在后台后切换到前台或者手机长时间休眠后唤醒应用有加载超时的现象。
分析:客户端需要保持定期的网络长连接链路,而Android系统版本迭代过程中随着系统对耗电量及流量的管理越发严格,会在休眠或者Idle过程中在系统级关闭网络连接,未能及时通知应用层连接已经断开,导致网络请求超时,超时请求等待时间过长,用户体验极差。
改善:为了改善长连接丢失后的请求超时情况,客户端针对Okhttp新增Ping帧心跳机制,流程如下:
(1)客户端基于HTTP/2协议进行网络通信,HTTP/2从底层实现了多路复用,多个请求共享一条链路进行请求,当客户端处于空闲状态时,链路依然保持存活。
(2)实现固定时间间隔发送Ping帧给服务端,如果服务端能在规定时间内返回结果,则继续下一轮心跳。
(3)一共心跳n(n为服务端发送心跳次数)次之后,如果仍然处于idle状态,则主动发送Goaway帧给服务端释放连接,然后释放本地连接。
(4)如果在n次心跳周期内检测到某次心跳超时,则直接释放本地连接,下次请求时重新发起请求。 - SSL/TLS握手过程深度优化
已有的HTTPS,HTTP/2协议需要设置连接,每次新的TLS连接都需要握手,以便创建共享的加密密钥,这个握手过程在标准TCP的握手过程之上还需要两个额外的来回过程(共有7次握手),会在请求效率上造成时延。TLS有几个特征可以用来消除额外的来回,比如重用一个会话session,两个标准会话重用机制是session IDs(RFC 5246)和session tickets(RFC 5077),使用其中一个技术,一个客户端可以重用之前创建的会话,这个会话是之前和服务器进行握手成功的,这样可以减少一次来回过程。
例子客户端支持TLS session tickets重用机制,session tickets是用只有服务端知道的安全密钥加密过的会话信息,最终保存到移动终端。移动端TLS握手时带上session tickets信息,只要服务器能成功解密就可以完成快速握手。 - 用户访问质量监控及网络容灾性优化
对访问质量的监控和容灾性上做的优化:
(1)考虑到在线用户数量激增的情况下,可能导致服务端性能压力过大,客户端增加了线上开关控制HTTP/2协议开启状态;一旦出现异常,可以及时调整开关回滚。
(2)对HTTP/2开启后增加异常埋点上报,如果有异常,能够通过监控平台及时发现问题,并且查询问题用户的异常详情。
(3)当HTTP/2请求发生异常时,客户端会发起降级重试机制,降级策略包含重试、协议降级、内置拔测、只能路由等策略,目的是为了增强客户端网络容灾性。
(4)在应用内增加网络型能统计数据监控,开发及运维人员可以全面监控网络性能。