Android
Addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are cached for 10 seconds.
DNS cachingIn Android 4.0 (Ice Cream Sandwich) and earlier, DNS caching was performed both by InetAddress and by the C library, which meant that DNS TTLs could not be honored correctly. In later releases, caching is done solely by the C library and DNS TTLs are honored.IOS
按照官方文档说法,iOS设备上每24小时刷新一次DNS缓存
SP(电信运营商)缓存有些不靠谱,有些缓存服务器(不多)会忽略网站DNS提供的TTL,自己设置一个较长的TTL,导致顶级DNS更新时不能及时拿到新的IP地址。
可以看出,在从Root DNS请求域名解析的过程中,有太多的层次影响DNS的获取,缓存是双刃剑,提高了获取DNS的速度,也会影响DNS在IP变更时不能及时更新到最新。
短连接 参考https://tech.meituan.com/SharkSDK.html
一、 合并域名。
- 域名得到了收编,减少了DNS调用次数,降低了DNS劫持风险。
- 针对同一域名,可以利用Keep-Alive来复用Http的连接。
- 客户端业务层不需要修改代码,后端业务服务也不需要进行任何修改。
二、 IP直连方案有下面几大优势:
- 摒弃了系统DNS,减少外界干扰,摆脱DNS劫持困扰。
- 自建DNS更新时机可以控制。
- IP列表更换方便。
此外,如果你的App域名没有经过合并,域名比较多,也建议可以尝试使用HttpDNS方案。参考: 对HTTPS中的证书处理:
其实在整个DNS链路上也是有DNS缓存的,理论上也是能够提高速度的。这个链路上的DNS缓存在PC用户上效果明显,因为PC用户的DNS链路相对稳定,信号源不会变来变去。但是在移动设备的用户这边,链路上的DNS缓存所带来的性能提升就不太明显了。因为移动设备的实际使用场景比较复杂,网络信号源会经常变换,信号源每变换一次,对应的DNS解析链路就会变换一次,那么原链路上的DNS缓存就不起作用了。而且信号源变换的情况特别特别频繁,所以对于移动设备用户来说,链路的DNS缓存我们基本上可以默认为没有。所以大部分时间是手机系统自带的本地DNS缓存在起作用,但是一般来说,移动设备上网的需求也特别频繁,专门为我们这个App所做的DNS缓存很有可能会被别的DNS缓存给挤出去被清理掉,这种情况是特别多的,用户看一会儿知乎刷一下微博查一下地图逛一逛点评再聊个Q,回来之后很有可能属于你自己的App的本地DNS缓存就没了。这还没完,这里还有一个只有在中国特色社会主义的互联网环境中才会有的问题:国内的互联网环境由于GFW的存在,就使得DNS服务速度会比正常情况慢不少。
基于以上三个原因所导致的最终结果就是,API请求在DNS解析阶段的耗时会很多。
那么针对这个的优化方案就是,索性直接走IP请求,那不就绕过DNS服务的耗时了嘛。
如果你还不熟悉NSURLProtocol应该怎么玩,看完和以及之后,你肯定就会了,其实很简单的。另外,刚才提到的作者(mattt)还写了,相当好用,是可以直接拿来集成到项目中的。
https://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html
三、建立链接本身是属于比较消耗资源的操作,耗电耗时。SPDY自带链接复用以及数据压缩的功能,所以服务端支持SPDY的时候,App直接挂SPDY就可以了。如果服务端不支持SPDY,也可以使用PipeLine,苹果原生自带这个功能。
这是我看过,讲述的最详细的文章。
http://www.gameres.com/767209.html
针对窄带宽、高时延、不稳定的移动网络
参数调优
慢启动阀值,窗口扩大,RTO调大(因为是高延时),针对性禁用快速回收,使用TCP_NODELAY选项,
对于移动APP,大部分网络交互都是HTTP并发短链接小数据量传输的形式,如果服务器端有10KB的数据返回,采用过去的慢启动机制时,效率会低一些,大概需要2~3个RTT才能完成数据传输,反应到用户体验层面就是慢,而把拥塞窗口cwnd初始值提升到10后,在大多数情况下都能在1个RTT的周期内完成应用数据的传输,这在移动网络这样的高时延、不稳定、易丢包的场景下,显得尤其意义重大。
TCP窗口是用于在接收端和发送端之间动态反映接收端读缓冲大小的变化,它的初始值就是读缓冲区设定的值,单位是字节,这个数字在TCP包头的16位窗口大小字段中传递,最大65535字节,如果嫌不够大,在TCP选项中还有一个窗口扩大的选项可供选择。
提升TCP吞吐量,最佳状态是在流量控制机制的调控下,使得发送端总是能发送足够的数据报文填满发送端和接收端之间的逻辑管道和缓冲区。其中逻辑管道的容量有专门的学名叫BDP(BandwidthDelayProduct,带宽时延乘积,BDP=链路带宽*RTT),在一个高带宽低时延的网络中,TCP包头中的16位窗口大小可能就不够用了,需要用到TCP窗口缩放选项,在RFC1323中定义,有兴趣可以研究一下
快速回收
(tcp_tw_recycle启用时必须同时启用本项,反之则不然,timestamps用于RTT计算,在TCP报文头部的可选项中传输,包括两个参数,分别为发送方发送TCP报文时的时间戳和接收方收到TCP报文响应时的时间戳。Linux系统和移动设备上的Android、iOS都缺省开启了此选项,建议不要随意关闭)
接入调度