HTTP1.0到2.0

2021-04-30  本文已影响0人  小幸运Q

HTTP1.0

"一来一回",每个请求都是一个TCP连接(端口不一定够用),建立连接开销大,服务端没法主动推送消息。

为了解决这些问题提出了Keep-Alive机制:
客户端添加字段connection:Keep-Alive,服务端处理完请求后不会关闭连接。但是为了防止连接数太多不释放设置了Keep-Alive timeout字段超时取消连接。利用Content-Length:xxx知道结束。

HTTP1.1

默认使用keep-alive,除非显式申明不用Connection:Close

(1)Chunk机制:
加上Transfer-Encoding:chunked,告诉客户端,响应的Body是分成了一块一块的,且块与块之间有分隔符,所有块的结尾也有特殊标记。

HTTP/1.1 200 OK
...
Transfer-Encoding:chunked
25
This is the data in the first chunk
1C
sequence 
0

(2)Pipeline与Head-of-line Blocking
Pipeline允许并发请求,Pipeline的Head-of-line Blocking要对请求按序处理,如果先请求的没处理则后请求的就会一直阻塞。为了避免这种问题一般默认关闭Pipeline。

HTTP1.1管道化的限制:

  1. 管道化要求服务端按照请求的顺序返回响应,因为请求和响应没有序号标记,无法将乱序的响应与请求关联起来。(HTTP队头阻塞)
  2. 客户端需要保持未收到的请求,当意外中断时重发
  3. 只有幂等请求才能管道化比如get和head
  1. 客户端定期轮训
  2. HTTP长轮训:服务器跟客户端建立连接,但是不取消,如果服务器有新消息就立刻返回,如果没有就等一段时间再返回一个空消息之后关闭连接。

HTTP2.0

HTTP2兼容HTTP1.1,位于HTTP1.1与TCP层之间,相当于一个转换层。

HTTP2的位置

(1)二进制分帧
请求1分为F1,F2,F3三个帧,请求2分成F4,F5两帧,每一帧都添加了基于流的序号。每个帧在流和连接上独立传输,到达后组装成消息。允许乱序发送,再根据流标记组装。

还是无法彻底解决TCP协议自身的“队头阻塞”的问题,只是将阻塞从报文一级下沉到了帧一级。TCP队头阻塞发生在滑动窗口内,需要集齐缺失的窗口内请求,要不然不发后面的ACK。(阻塞的本质是不凑齐不提交给应用层处理)

但是二进制分帧还是降低了管道化阻塞发生的可能。因为对于返回的请求,后来的如果先分帧响应,那么先来的也无法阻塞它的响应。(响应可以认为是一次新的发送)

因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。

HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数

(2)头部压缩

在1.1图片压缩的基础上,对报文头部压缩。

HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分。

这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

(3)服务器推送(鸡肋功能)

主动将客户端可能不需要的css和js在请求index.html的时候发送给对方。


用谷歌基于UDP的QUIC协议即可。

HTTP各版本之间的区别

HTTP 1.0 HTTP 1.1 HTTP 2.0
不默认http-alive 默认支持http-alive
(长连接)

支持只发送header

Chunk机制

管道化(阻塞型并发)

断点续传
基于二进制分帧的
多路复用
(无阻塞并发)

header压缩

服务器推送

定制流优先级
上一篇下一篇

猜你喜欢

热点阅读