- 4. 参考文章
================================================================================
对于Android来说,开发者可以轻松的打造一套 MVP + Retrofit + RxJava 的框架来处理所有的网络请求。因为 Retrofit下层封装的OkHttp
是非常强大的网络库,而 RxJava
又能够很好的帮我们处理线程切换的问题。
但是对于大型的App来说,仅仅是使用这些是不够的,它太机械,不能帮我们处理复杂多变的网络情况。
在我的上个公司,智能设备的网络连接是老大难问题,有时候设备连不上Wifi的情况下,开发人员去跟进,到最后总会丢出一句:“设备就是Ping不通网络啊” 以此把锅甩在了网络上。而这些客户,家里同时存在多种同类型的设备,竞品设备的连接却毫无问题…
所以无论是哪一端,当用户量变多时,网络的性能优化都是不可忽视的点,虽然网络确实有其独特的不可控性和复杂性,但是每一端都可以尽自己所能去优化到一个较好的情况。
这个“较好的情况”有下面几个标准:
-
避免重复的上传、下载
-
富媒体、JS/CSS/HTML 都有压缩
-
对于选择压缩算法,优化到最适合业务的情况
-
请求合并
-
网络请求失败的重试必须有明显的结束条件
-
有连接建立兜底的能力
-
…
================================================================================
网络性能优化,是性能优化专题中不可忽视却又不可控的一点。
之所以不可控,是因为 网络 和CPU、磁盘、内存这些本地资源相比,网络是外部资源,它有自己独特的性能瓶颈,程序员突破不了这些瓶颈,令人困扰。
为了尽可能优化网络性能,总结出下面几大问题,可以从这些问题入手,来进行优化:
-
业务成功率
-
业务网络延时
-
业务宽带成本
-
业务安全性
下面有两个场景是用户真实可以遇到的:
-
当发消息的时候走进了电梯
-
在演唱会时分享朋友圈
上面两个场景就体验来说,是最有可能出现发送失败的地方。
而正好,这两个场景分别代表了两种典型的网络差的场景,进电梯代表了网络信号差,而演唱会则代表了拥塞网络,程序如果处理不当都会直接影响业务的成功率。
2.1.1 弱信号 / 弱网
可以简单的看成手机信号只有一格的时候,这时不仅仅是信令(无线网络其实通信的时候都是一个个信令)发出去困难,而且还有可能导致不断切换网络、切换基站。App能做的,就是在应用层做重试,因为很大概率这个弱信号只是一时的。
2.1.2 拥塞网络
这个我们熟悉,当我们把网络的消息传输看成是一个 生产消费者模型,就是一端在不断发消息,一端在处理消息,
拥塞网络的本质就是: 生产者生产消息的速度大于消费者处理消息速度,这时候网络状态就过载了。
如果我们App不断重试,只会导致拥塞更为严重。这个时候能做的就是让自己的非核心业务不要捣乱,不要排队,让核心业务的数据量更少,协议来回更少。
成功率直接代表了业务的成功和失败。
而网络延时相比起来没那么直接,但是 慢 会带来不爽,按我们公司的话来说,就是“等待时焦虑”,也是会流失用户的。
这个慢,就必须从一个数据包的发送历程开始说起,可以参考下图:
2.2.1 DNS解释
域名换ip。这一步看似简单却充满陷阱,10分钟的DNS的Cache过期时间,200~2000ms不等的DNS耗时,坑了无数应用。
解决无非有三个策略:
-
ip直连
-
域名重用
-
HttpDNS(利用云服务器,通过自定义的协议获取域名对应的IP地址,甚至是列表)
2.2.2 建立连接
大多数应用都是基于TCP,所以就是三次握手建立TCP连接。这一步的耗时,如果是长连接的话就是一次消耗,但是短连接的话就是多次消耗(因为Http的无状态性)。要维护的化就需要心跳包,心跳包多,会耗电,特别是当心跳间隔等于移动网络状态机Active-Idle切换间隔时,简直就是悲剧。
同时对于移动网络来说还会增加信令通道的负担,着也是当年那个轰动一时的微信信令风暴的部分原因。(信令风暴:就是发送心跳包过多或者过快,超过了服务器的处理速度,最终会导致大量占用网络资源、服务器不可用)。
而心跳包少了,会让连接在NAT中超时,导致长连接断开。在建立连接的过程中,TCP会进行一些商定,其中影响网络时延最明显的就是窗口。
2.2.3 接受窗口
用于拥塞控制。
客户端同一时间发送多少TCP数据包,当前的宽带有没有被充分利用,直接影响发送的速度。而让窗口太少的原因无非有几个:
-
服务器的Receive Buffer较小
-
因为慢启动,而包又太小,刚刚连接,慢启动会逐步放大窗口,没有等放大完,数据就发完了
-
Window size scaling factor
失效,这里最有可能的原因是网络代理,失效的结果就窗口最大只有65536字节。
窗口本身就是Tcp拥塞控制的一部分,但有时App为了能自己控制,也是想尽了办法。利用应用层分片大小可以做更严格的拥塞策略;多连接和长连接一定程度上可以绕过拥塞策略中的慢启动。
在云时代,已经有各种各样的提升业务成功率和网络延时的优秀组件,比如 QQ的MSF,QZONE的WNS~
如果将流量列入到影响网络的原因中,那么就必须要思考应用的业务宽带成本了。
对于视频、图片这些富媒体业务,每天在宽带成本上的投入,跟烧钱没有什么区别。
如何在降低这些成本的同时,不会影响用户体验呢?策略有: 压缩、增量、去重复三种。
2.3.1 压缩
-
图片用
WebP
压缩、PNG
压缩,还可以使用像progressive jpeg
的不同程度压缩来替代大中小图 -
视频用
H264
、H265
压缩 -
文本是用
gzip
和其他ZIP压缩 -
传输数据使用
json
、protobuf
等。
除此之外还有一些细节,例如
-
图片的尺寸在不同分辨率的上要下载不同的尺寸,设计时要注意
-
WebP图片的编码和解码对于手机是有压力的,CPU消耗是JPEG的3倍以上,编码耗时也比JPEG长不少。所以不要在性能压力大的时候使用,建议解码后在本地保存成JPEG,以降低下次解码的压力。
-
对于文本,也有通过改变编码方式来降低流量,UTF-8、UTF-1
6、GBK都有不同的编码方式,虽然现在Unicode流行于编码界,但是了解这些编码的发展历史、编码算法,可以利于我们对优化流量有一定的帮助。
2.3.2 增量
即增量更新。常见于列表上拉加载、下拉更新、左滑删除。
所以这明显是要看场景使用的,当你的RecyclerView怼满了2000个item时,一次性加载那就是灾难,而最多只有20个item时还做增量,就会导致我们的协议复杂度增加,得不偿失。
2.3.3 去重复
该问题很简单,而且很常见,比如地图SDK重复下载地图块、横竖屏幕切换WebView的内容,重复下载,这些都比较常见。
而像 压缩包里面的图片和没有压缩的内容重复、CSS里面的内嵌图片与压缩包里的图片重复这些问题则较为隐蔽,一般也没有这个精力去查问题。
怎样防止被第三方窃听/篡改或冒充,防止运营商劫持,同时又不影响性能?
现在已经普遍的使用 TLS
协议来保证网络传输的安全性,HTTP + TLS = HTTPS
在 Android4.4开始,就已经支持非常完善的 TLS1.2
版本,所以业务安全性问题在现在已经基本得到保障。
使用TLS安全协议,已经解决了两个问题:1. 保证安全 2.降低加密成本
在保证安全上:
-
使用加密算法组合对传输数据加密,避免被窃听和篡改。
-
认证对方身份,避免被第三方冒充。
-
加密算法保持灵活可更新,防止定死算法被破解后无法更换,禁用已被破解的算法。
在降低加密成本上:
-
用对称加密算法加密传输数据,解决非对称加密算法的性能低以及长度限制问题。
-
缓存安全协议握手后的密钥等数据,加快第二次建连的速度。
-
(TLS1.3版本)加快握手过程:2RTT-> 0RTT。加快握手的思路,就是原本客户端和服务端需要协商使用什么算法后才能加密发送数据,变成通过内置的公钥和默认的算法,在握手的同时就把数据发出去,也就是不需要等待握手就开始发送数据,达到0RTT。
具体点可以查看该篇文章:TLS协议分析 与 现代加密通信协议设计
目前移动端在该问题上可以做的事情不是很多。 唯一可以做的就是升级 TLS
版本,因为现在的主流版本还是 TLS1.2
,它的优点是保证传输安全,缺点是建立连接速度。 而 TLS1.3
版本进行了优化,提升连接速率。像微信就自行实现升级到了 TLS1.3
.
TLS 1.2 和 1.3 的对比可以查看这篇文章: TLS1.3 VS TLS1.2,让你明白TLS1.3的强大
========================================================================
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-8C3N1pEM-1718825185898)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取