一、正常一个网络请求过程
正常一条网络请求需要经过:
- DNS解析,请求DNS服务器,获取对应的IP地址
- 与服务端建立连接,TCP三次握手,安全协议的同步流程
- 连接建立完成,发送和接受数据,解码数据。
优化点:
- 直接使用IP地址,除去DNS解析的流程
- 不要每个请求都重复建立连接,复用连接使用同一条连接(长连接)
- 压缩数据,减少传输数据的大小
二、正常的DNS流程
DNS完整的解析流程:
先动本地系统缓存获取,偌没有就到最近的DNS服务器获取。
偌依旧没有,就到主域名服务器获取,每一层都有有缓存。
为了域名解析的实时性,每一层的缓存都有一个过期时间。
缺点:
缓存时间过长,域名更新不及时,设置的端,单量的DNS解析请求影响速度
域名劫持,容易被中间人攻击或运营商劫持,把域名解析到第三⽅IP地址,劫持率⽐较⾼。
DNS解析过程不受控制,⽆法保证解析到最快的IP
⼀次请求只能解析到⼀个域名
处理DNS耗时和防劫持的方式
HTTPDNS原理就是:
⾃⼰做域名解析⼯作,通过HTTP请求后台去拿到域名对应的IP地址,可以解决上述问题。
域名解析与请求分离,所有的请求都直接⽤IP,⽆需DNS解析,APP定时请求HTTPDNS服务器更 新IP地址即可
通过签名等⽅式,保证HTTPDNS请求的安全性,避免被劫持
DNS解析有⾃⼰控制,可以确保更具⽤⼾所在地返回就近的IP地址,或者根据客⼾端测速结果使⽤ 速度最快的IP
⼀次请求可以解析多个域名
三、TCP连接耗时优化
解决思路就是:复用接连
- 不⽤每次重新建⽴连接,⽅案是⾼效的复⽤连接
HTTP1.1版本产生的问题:
HTTP1.1 的问题是默认开启的keep-alive,⼀次的连接只能发送接收⼀个请求,同时发起多个请求,会产⽣问题。
若串⾏发送请求,可以⼀直复⽤⼀个连接,但是速度很慢,每个请求都需要等待上⼀个请求完成再发 送,也产⽣了连接的浪费,没⽤充分的利⽤带宽
若并⾏发送请求,那么⾸次请求都要TCP三次握⼿建⽴新的连接,即使第⼆次请求可以复⽤连接池的 连接,但是会导致连接池的连接过多,对服务端资源产⽣浪费,若限制保持的连接数,会有超出的连 接仍要每次建⽴连接。
HTTP2.0 提出了多路复⽤的⽅式解决HTTP1.1的问题:
HTTP2 的多路复⽤机制也是复⽤连接,但是它的复⽤的这条连接⽀持同时处理多条请求,所有的请求 都可以并发的在这条连接上进⾏,解决了并发请求需要建⽴多次连接的问题
HTTP2 把连接⾥传输的数据都封装成⼀个个stream,每个stream都有⼀个标识,stream的发送和接 收可以是乱序,不依赖顺序,不会有阻塞的问题,接收端可以根据stream的标识区分属于哪个请求, 在进⾏数据拼接,最终得到数据
HTTP2.0 TCP队头阻塞
HTTP2还是有问题存在,就是队头阻塞,这是受限于TCP协议,TCP协议为保证数据的可靠性,若传 输过程中有⼀个TCP的包丢失,会等待这个包重传之后,才会处理后续的包.
HTTP2的多路复⽤让所 有的请求都在同⼀条连接上,中间有⼀个包丢失,就会阻塞等待重传,所有的请求也会被阻塞
HTTP2.0 TCP队头阻塞解决方案
- 这个问题需要改变TCP协议,但是TCP协议依赖操作系统实现以及部分硬件的定制,所以改进缓慢。
- 于是Google提出了QUIC协议,相当于在UDP的基础上在定义⼀套可靠的传输协议,解决TCP的缺陷, 包括队头阻塞,但是客⼾端少有介⼊
四、传输数据优化
传输数据有⼤⼩,数据也会对请求速度有影响。主要优化两个方面:
压缩率,⽽是解压序列化反
序列化的速度。使⽤Protobuf 可以⽐json的数据量⼩⾄少⼀个数量级压缩算法的选择,⽬前⽐较好的是Z-Standard HTTP的请求头数据的在HTTP2中也进⾏了压缩。
五、弱⽹优化
根据不同的⽹络设置不同的超时时间
六、数据安全优化
使⽤Https,是基于http协议上的TLS安全协议,安全协议解决了保证安全和降低加密成本
1、安全上
使⽤加密算法组合对传输的数据加密,避免被窃听和篡改
认证对⽅⾝份,避免被第三⽅冒充
加密算法保持灵活可更新,防⽌定死算法被破解后⽆法更换,禁⽌已被破解的算法
2、降低加密成本
⽤对称加密算法加密传输的数据,解决⾮对称加密算法的性能低和⻓度限制的问题
缓存安全协议握⼿后的秘钥等数据,加快第⼆次建⽴连接的速度
3、加快握⼿过程2RTT -> 0RTT。加快握⼿的思路,原本客⼾端和服务端需要协商使⽤什么算法后才 可以加密发送数据,变成通过内置的公钥和默认算法,在握⼿的同时,就把数据发送出去,不需要等 待握⼿就开始发送数据,达到0RTT
3.充分利用缓存
- Get请求可以被缓存,Get请求也是幂等的,
- 简单的处理缓存的80%需求
使⽤Get请求的代码设置如下:
///objective-c代码
NSURLCache *urlCache =[[NSURLCache alloc]initWithMemoryCapacity:4 *1024 * 1024
diskCapacity:20 * 1024 *1024 diskPath:nil];
[NSURLCachesetSharedURLCache:urlCache];
4、控制缓存的有效性
1、⽂件缓存:借助ETag或者Last-Modified判断⽂件缓存是不是有效
Last-Modified
⼤多采⽤资源变动后就重新⽣成⼀个链接的做法,但是不排除没有换链接的,这种情况下就需要借助
ETag
orLast-Modified
判断⽂件的有效性Last-Modified
资源的最后修改时间戳,与缓存时间进⾏对⽐来判断是否过期,请求时返回If- Modified-Since
,返回的数据若果没变化http返回的状态码就是403
(Not changed),内容为空,节省 传输数据
ETag和If-None-Match
- HTTP 协议规格说明定义ETag为“被请求变量的实体值” 。另⼀种说法是,ETag是⼀个可以与Web 资源关联的记号(token)。
- 它是⼀个 hash 值,⽤作 Request 缓存请求头,每⼀个资源⽂件都对应⼀ 个唯⼀的 ETag 值。如果Etag没有改变,则返回状态码304,返回的内容为空
下载的图⽚的格式最好是WebP格式,因为他是同等图⽚质量下最⼩数量的图⽚,可以降低流量损失