Android 网络优化
一次网络请求的操作是从 DNS 解析开始的,然后建立连接并发送数据到服务端,随后读取从服务端返回的数据,最后将连接释放,一次网络请求操作也就结束了。接下来就从 DNS 解析开始分析都有哪些方面可以做进一步的优化。
DNS 解析优化
安全方面
首先是防劫持,可考虑使用 HttpDns。这里需要注意 HttpDns 只是一个概念,并不是一个现有的开源库。它与传统的 DNS 解析的区别在于 HttpDns 会绕过运营商的 DNS 服务器,直接与 DNS 服务器的 80 端口进行交互,有效地防止了域名劫持。
目前业内主要由第三方厂商提供实现了 HttpDns 的 SDK,比较普及的是阿里云和腾讯云的 HttpDns Service。但是这两者的使用具有一定的成本:开发者需要在它们的平台注册并获取开发者 key,并且部分服务是收费的。对于普通开发者而言,可以考虑使用七牛云提供的免费的 happy-dns。
速度方面
关于 DNS 解析的速度优化方面,可从以下几个方面进行突破:
- IP 直连方式。经常会针对不同的开发环境使用,比如针对在 qa、staging 测试环境下,可以直接配置 IP 白名单,跳过 DNS 解析流程。
- DNS 解析超时。当在做网络请求时,如果网络设备切换路由,访问网络出现长时间无响应,很久之后会抛出 UnknownHostException,并且我们在 OkHttp 中设置的 connectTimeout 属性对 DNS 的解析不起作用。
网络请求缓存优化
实际上有时在做网络请求数据可达优化的时候,经常会不可避免地与本地持久化绑定在一起。比如当一次网络请求失败时,我们需要将这次请求保存在本地,并尝试重新发送;或者请求数据成功,我们需要将数据缓存在本地,当下一次请求数据展示 UI 之前,先将缓存中的数据展示到页面,只有当新的请求返回数据之后,再次刷新页面。
幂等性
HTTP 方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。举一个例子:当我们点外卖付款时,服务端扣款成功后发送给客户端一条扣款成功的消息,但是如果此时由于网络问题,客户端并没有成功接收到此消息,用户就有可能认为没有付款成功,甚至是尝试再次付款。
幂等性就是为了解决这种问题,但是它属于代码设计层面的技巧,并不是一个实体方法或者开源库。实现幂等性需要客户端和服务端协同合作实现。
总结
DNS 解析优化,分安全性和速度提升两方面。
网络请求数据缓存,对于请求返回的数据需要缓存到本地数据库中。实际上,在某些场景中对于请求对象 Request 自身也需要做缓存操作。比如“发送埋点”的请求,这样请求失败就将其保存到本地数据库中,当 App 重启或者重新接收到连接网络的时候,重新尝试发送之前失败的请求。
幂等性并不是一个非常大众化的概念,很多开发者甚至没有听说过这个概念。但是在网络架构设计中却是一个比较重要的原则。
其它:
连接服务器优化策略:
- 不用域名,用 IP 直连(说下 DNS )
- 服务器合理部署
获取数据优化策略:
- 连接复用
- 请求合并
- 减小请求数据大小:对于 POST 请求,Body 可以做 Gzip 压缩,如日志。
- 减小返回数据大小
- 使用 Gzip 压缩
- 精简数据格式
- 对于不同的设备不同网络返回不同的内容 如不同分辨率图片大小
- 需要数据更新时,可考虑增量更新。如常见的服务端进行 bsdiff,客户端进行 bspatch。
- 支持断点续传,并缓存 Http Resonse 的 ETag 标识,下次请求时带上,从而确定是否数据改变过,未改变则直接返回 304
- 缓存获取到的数据,在一定的有效时间内再次请求可以直接从缓存读取数据。
当前使用网络框架它们做了哪些优化比如 OKHTTP(Socket 连接池、Http缓存、责任链)、Retrofit(动态代理)。
备注
参考资料:
Android 工程师进阶 34 讲-拉钩