谈谈如何对网络请求进行优化?
网络请求速度的影响因素: 网络库实现、服务器性能、网络链路的质量
网络优化
优化的核心内容:
- 速度: 在网络正常或者良好的时候,怎样更好地利用带宽,进一步提升网络请求速度。
- 弱网络: 移动端网络复杂多变,在出现网络连接不稳定的时候,怎样最大程度保证网络的连通性。
- 安全: 网络安全不容忽视,怎样有效防止被第三方劫持、窃听甚至篡改。
网络请求流程
要想进行网络优化,必须先了解整个网络请求的流程,借用邵文老师文章里的图:
在请简述一次http网络请求的过程?一文中,也有讲过网络请求的流程
- DNS解析:通过DNS服务器,获取对应域名的IP地址。这里需要关注DNS解析耗时情况、运营商LocalDNS的劫持、DNS调度情况。
- 创建连接:与服务器建立连接,包括TCP三次握手、TLS密钥协商等工作。需要关注多个IP/端口该如何选择、是否要使用HTTPS、能否可以减少甚至省下创建连接的时间。
- 发送/接收数据:在建立连接后,就可以服务端进行数据交互了。这里需要关注,如何根据网络状况将带宽利用好,怎么样快速地侦测到网络延时,在弱网络下如何调整包大小等问题。
- 关闭连接:这里主要关注主动关闭和被动关闭两种情况。
网络库
目前 Android 用的比较多就是OkHttp,网络库核心作用主要以下三点:
- 统一编程接口:同步和异步请求的接口简单,统一进行数据处理(JSON、XML、Protocol Buffers等)。
- 全局网络控制:网络库内部可以做统一的网络调度、流量监控以及容灾管理等工作。
- 高性能:要实现高性能,主要体现在速度,CPU、内存、I/O的使用,以及失败率、崩溃率、协议的兼容性等方面
直到读到邵文老师的这篇文章,才了解到还有很多其他高质量,跨平台的网络库,譬如Chromium的Cronet以及微信Mars
对比
| OkHttp | Cronet | Mars | |
|---|---|---|---|
| DNS管理 | 支持DNS缓存 支持对接自己的 HTTPDNS |
支持DNS缓存 支持对接自己的 HTTPDNS |
支持DNS缓存 支持对接自己的 HTTPDNS |
| 连接管理 | 对于HTTP连接,每个 域名最多缓存5个, 默认KeepTime为5分钟。 对于HTTP/2连接, 每个域名都共用一个H2连接 |
对于HTTP连接,每个 域名最多缓存6个 对于HTTP/2连接, 每个域名都共用一个H2连接 |
支持复合连接, 没有连接管理 |
| 并发模型 | 使用多线程实现并发,实 际执行线程数受队列机制 控制,最大64,每个Host 限制5个 |
每个Host对应一个线程, 每个线程可创建6个 非阻塞Sockect请求玩网络. 同一时间最多16个线程 |
每个短连都是一个线程, 没有线程限制 |
| I/O 模型 | 阻塞Socket,使用 Okio包装Socket进行流读写 |
epoll+非阻塞Sokect | epoll+非阻塞Sokect |
| 协议支持 | HTTP/1.1、HTTP/2.0 TLS1.1、TLS1.2 |
HTTP/1.1、HTTP/2.0、 QUIC、TLS1.1、 TLS1.2、TLS1.2 |
信令网络、只支持TCP |
| 网络质量监控 | 默认不支持, 需要第三方库配合 |
Predictor用于收集使用 并预测网络行为, NQE提供当前网络评估 |
SDT模块支持网络侦测与诊断 |
| 长连接 | 默认不支持 | 默认不支持 | 默认支持 |
| 跨平台 | Java实现,无法跨平台 | C++实现,可跨平台 | C++实现,可跨平台 |
| 二次开发难度 | 容易 | 实现复杂,不容易扩展 | 实现复杂,不容易扩展,比Cronet简单一些 |
大公司通常都会有个大网络平台,可以在接入层中做各种各样的网络优化.
优化方案
优化方案也是根据网络请求流程一步步来的
HTTPDNS
DNS解析,默认使用的是运营商的LocalDNS服务。这块耗时在3G网络下可能是200~300ms,4G网络也需要100ms。
解决方案:通过HTTP请求后台获取域名对应的IP,HttpDNS基于Http协议的域名解析,替代了基于DNS协议向运营商LocalDNS发起解析请求的传统方式,可以避免LocalDNS造成的域名劫持和跨网访问问题,解决域名解析异常带来的困扰。
连接复用
这里的优化和网络协议相关,创建连接要经过TCP三次握手、TLS密钥协商,连接建立的代价是非常大的。
Http/1.1增加了 keep-alive,Http/2.0的多路复用都可以提升连接复用率。
解决方案:复用连接,网络库的连接管理,把连接放到连接池中,减少建立连接的耗时。
压缩与加密
数据压缩
优化数据传输和接收,减少数据传输。对于HTTP请求来说,数据主要包含:
- 请求 URL
- 请求 Header
使用HTTP/2.0连接本身的头部压缩技术 - 请求 Body
一是数据通信协议的选择,在网络传输中目前最流行的两种数据序列化方式是JSON和Protocol Buffers
另一个是压缩算法的选择,通用的压缩算法主要是如gzip,Google的Brotli或者Facebook的Z-standard都是压缩率更高的算法。
其中有数据是图片的,可以使用webp等高压缩的格式,还可以根据网络状态下载不同的缩略图。
加密安全
数据安全在网络请求中也非常重要,基于HTTPS的HTTP/2通道,已经有了TLS加密。HTTP 和 HTTPS 相比,HTTPS 的开销更大,也是优化的一个重点。
其他优化
- 增加CDN服务
- 使用好的云服务,阿里云或者腾讯云等
- 使用新技术 QUIC、IPv6等
总的来说,网络优化我们需要综合用户体验、带宽成本以及硬件成本等多个因素来考虑