HTTP各版本
# HTTP 1.0
短连接:每一个请求建立一个 TCP 连接,请求完成后立马断开连接。
导致的问题:
- 连接无法复用:每次请求都经历三次握手和慢启动
- 三次握手在高延迟的场景下影响较明显
- 慢启动则对文件类大请求影响较大
- 队头阻塞:任务被放在一个任务队列中串行执行,一旦队首的请求处理太慢,就会阻塞后面请求的处理
# HTTP1.1
长连接
相比HTTP1.0,HTTP1.1默认支持长连接keep-alive,使用HTTP 流水线技术(HTTP pipelining,也有翻译为管道化连接),在一个TCP连接内,多个HTTP请求可以并行,下一个HTTP请求在上一个HTTP请求的应答完成之前就发起。
分块传输编码
每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。
引入更多缓存控制机制:如cache-control、etag等
请求消息和响应消息都支持 Host 头域
新增了 OPTIONS,PUT, DELETE, TRACE, CONNECT 方法
HTTP1.1 如何解决 HTTP 的队头阻塞问题?
- 并发连接:对于一个域名允许分配多个长连接,相当于增加了任务队列(chrome 支持6个长连接)
- 域名分片:在一个域名下分出多个二级域名,这样并发的长连接数就更多
# HTTP2.0
二进制分帧
在应用层与传输层之间增加一个二进制分帧层,以此达到在不改动 HTTP 的语义,HTTP 方法、状态码、URI 及首部字段的情况下,突破HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。在二进制分帧层上,HTTP2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 HTTP1.x 的首部信息会被封装到 Headers 帧,而我们的 request body 则封装到 Data 帧里面。
首部压缩
使用
HPACK算法进行首部压缩在服务器和客户端之间建立哈希表,将用到的字段存放在这张表中,那么在传输的时候对于之前出现过的值,只需要把索引(比如0,1,2,...)传给对方即可,对方拿到索引查表就行了。这种传索引的方式,可以说让请求头字段得到极大程度的精简和复用。
其次是对于整数和字符串进行哈夫曼编码,哈夫曼编码的原理就是先将所有出现的字符建立一张索引表,然后让出现次数多的字符对应的索引尽可能短,传输的时候也是传输这样的索引序列,可以达到非常高的压缩率。
多路复用
对于 HTTP/1.x,即使开启了长连接,请求的发送也是串行发送的,在带宽足够的情况下,对带宽的利用率不够,HTTP/2.0 采用了多路复用的方式,可以并行发送多个请求,提高对带宽的利用率。
请求优先级
HTTP/2.0 对数据流可以设置优先值,这个优先值决定了客户端和服务端处理不同的流采用不同的优先级策略。
服务端推送
在 HTTP/2.0 中,服务器可以向客户发送请求之外的内容,比如正在请求一个页面时,服务器会把页面相关的 logo,CSS 等文件直接推送到客户端,而不会等到请求来的时候再发送,因为服务器认为客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源。