上一节写到网络层搭建,关于网络优化真的是不去学习感觉良好,越去学习越觉得自己的知识不够用。这一节主要针对网络优化进行一个自我总结。
主要会讲这些方面:
一、 针对请求响应速度优化
二.、针对网络环境体验优化
1. 针对请求响应速度优化:
在API发起请求建立链接的环节,大致会分这些步骤:
发起请求
DNS域名解析得到IP
根据IP进行三次握手(HTTPS四次握手),链接建立成功
1.1 跳过DNS域名解析
其实在整个DNS链路上也是有DNS缓存的,理论上也是能够提高速度的。这个链路上的DNS缓存在PC用户上效果明显,因为PC用户的DNS链路相对稳定,信号源不会变来变去。但是在移动设备的用户这边,链路上的DNS缓存所带来的性能提升就不太明显了。因为移动设备的实际使用场景比较复杂,网络信号源会经常变换,信号源每变换一次,对应的DNS解析链路就会变换一次,那么原链路上的DNS缓存就不起作用了。而且信号源变换的情况特别特别频繁,所以对于移动设备用户来说,链路的DNS缓存我们基本上可以默认为没有。所以大部分时间是手机系统自带的本地DNS缓存在起作用,但是一般来说,移动设备上网的需求也特别频繁,专门为我们这个App所做的DNS缓存很有可能会被别的DNS缓存给挤出去被清理掉,这种情况是特别多的,用户看一会儿知乎刷一下微博查一下地图逛一逛点评再聊个Q,回来之后很有可能属于你自己的App的本地DNS缓存就没了。这还没完,这里还有一个只有在中国特色社会主义的互联网环境中才会有的问题:国内的互联网环境由于GFW的存在,就使得DNS服务速度会比正常情况慢不少。
基于以上三个原因所导致的最终结果就是,API请求在DNS解析阶段的耗时会很多。
那么针对这个的优化方案就是,索性直接走IP请求,那不就绕过DNS服务的耗时了嘛。这样还能防止DNS 劫持。
另外一个,就是上面提到的建立链接时候的第三步,国内的网络环境分北网通南电信(当然实际情况更复杂,这里随便说说),不同服务商之间的连接,延时是很大的,我们需要想办法让用户在最适合他的IP上给他提供服务,那么就针对我们绕过DNS服务的手段有一个额外要求:尽可能不要让用户使用对他来说很慢的IP。
所以综上所述,方案就应该是这样:本地有一份IP列表,这些IP是所有提供API的服务器的IP,每次应用启动的时候,针对这个列表里的所有IP取ping延时时间,然后取延时时间最小的那个IP作为今后发起请求的IP地址。
1.2 传输数据量的优化
这个很好理解,传输的数据少了,那么自然速度就上去了。这里没什么花样可以讲的,就是压缩呗。各种压缩。
1.3 最新数据检验(这个针对网络比较差的环境下)
这个需要后台返回(Last-Modified 或者 ETag)才能实现。
Last-Modified: 是资源最后修改的时间戳,往往与缓存时间进行对比来判断缓存是否过期。
ETag:它是一个 hash 值,用作 Request 缓存请求头,每一个资源文件都对应一个唯一的 ETag 值。服务端不会每次都会返回文件资源。客户端每次向服务端发送上次服务器返回的 ETag 值,服务器会根据客户端与服务端的 ETag 值是否相等,来决定是否返回 data。(类似对本地数据和服务器数据进行md5, 然后对比2者数据是否一致 )
Last-Modified 和 ETag 响应结果差不多,如果是最新数据,httpCode会返回304 ,data不会返回。如果不是,正常返回数据。
1.4 输数据速度优化
TCP协议在通信的双方建立连接的时候,先慢慢的发包。比如我们可以先让发送方发一个包,等这个包被 ack 之后,我们再发 2 个包,这 2 个被 ack 之后再发 4 个包,以此类推,让一次所发的包数量慢慢增加,这就是慢启动。打个比方,这个过程非常像大家使用自来水时,慢慢拧开水龙头。
慢启动的影响确实会比较大,它不仅仅发生在建立连接的初期。一条 TCP 通道在健康通讯一段时间之后,如果丢包率突然上去,导致大量的包发送超时,Slow start 有可能会被重新启动,这也是为什么有时候明明带宽足够,如果丢包率过高(网络不稳定),网速却上不去。
和 TCP 的慢启动相比,UDP 显得非常不文明,UDP 会在连接的一开始,就将流量开至最大,这也是为什么现在有不少基于 UDP 的类 TCP 方案,可以避免 TCP 慢启动所带来的影响,这种做法虽然高效却不值得称赞,是对现有公平秩序的破坏,所以有些运营商会对大流量的 UDP 采取惩罚措施。
为了加快传输速度,可以建立多个tcp/ip连接, 把多个请求放到不同的tcp/ip连接中。
针对建立多个tcp/ip连接过程中的一些问题:
问题一:是不是tcp/ip连接越多网速越快呢?
显然不会,当传输的吞吐量达到一定量之后,整个网络层会进入交通拥堵状态,导致整体速度延迟。就好像水管一样,约占水管的1/3的水流进水管,那么还有2/3的水管空余。这时候多开一个tcp/ip连接,等于往水管加大传输量,这样效率就提升了。那如果同时开4个tcp/ip通道,这就导致4个tcp/ip通道一起占用水管,整体传输速度就下降了。
问题二:tcp/ip连接开启多少好呢?
为了较好的网络体验,不同的网络状态下tcp/ip连接个数也不一样。我针对(2G 3G 4G WIFI) 分别开出的最大通道是(1,2,3,3)。
二.、针对网络环境体验优化
2.1 使用缓存手段减少请求的发起次数
对于大部分API调用请求来说,有些API请求所带来的数据的时效性是比较长的。比如电商项目的商品详情等。那么我们就可以针对这些数据做本地缓存,这样下次请求这些数据的时候就可以不必再发起新的请求。
2.2 使用策略来减少请求的发起次数
如果是界面刷新请求这种,而且存在重复请求的情况(下拉刷新时,在请求着陆之前用户不断执行下拉操作),那么这个时候,后面重复操作导致的API请求就可以不必发送了。
2.3 使用重发避免网络抖动带来的请求失败
网络经常出现抖动,本来大部分请求都是 100ms 左右,突然冒出来一两千毫秒的,甚至有10、20秒的延迟情况。如果一次失败就反馈给用户,这样做是很不友好的。针对这种情况可以使用做一个重发机制,允许请求被重发,重发次数一般3次可以排除网络抖动。(注意: 针对特殊场景 API是不能重发的 比如:支付等)
2.4 监听网络状态 针对重要接口恢复请求
在应用实际使用过程中,用户在 坐电梯、地铁过隧道等场景下,导致网络状态发生改变。可以给发起请求的API一个网络监听,当网络恢复的时候重新请求。
总结:
关于网络优化的方案还有很多,这里列举了一些。有什么好的方案希望大家能跟我分享一下,先谢谢了🙏。
网友评论