什么是 HTTP2?
HTTP2 即超文本传输协议 2.0。是由互联网工程任务组(IETF)的 Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。主要是为了优化性能,前身是 Google 的 SPDY 。是兼容 HTTP1.1的
HTTP1.1 发布于 1999年。HTTP2 发布于 2015年5月
HTTP2 更新了什么?
- 二进制协议。可以定义额外的帧内容。
- TCP 链接复用。(并不是很有效)
- HTTP/2 头部压缩(HPack)
- 一份静态表(Static Table)
包含常见的头部名称,以及特别常见的头部名称与值的组合。静态表规则地址,可以看到一个 POST 的请求头可以转化成一个数字来表示,缩小了很多。
- 一份动态表(Dynamic Table),可以动态地添加内容
- 基于静态哈夫曼码表的哈夫曼编码(Huffman Coding)
4.ALPN
兼容性考虑(HTTP2、HTTP1.1),客户端告诉服务端所有支持的方式,服务端选择一个最优的来通信。
5.Server Push
在 HTTP 1.1 里,在同一个 TCP 连接里面,上一个回应(Response)发送完了,服务器才能发送下一个,但在 HTTP/2 里,可以将多个回应一起发送。
如何支持 HTTP2
Nginx 1.9.5+ 支持 HTTP2, 高版本的 Nginx 不支持 IE6 的 HTTPS(你们没看错我们还兼容 IE6)。
我们可以通过 Chrome 浏览器开发者工具的 Network 来查看当前请求使用的协议(Protocol 字段)
HTTP1、HTTP1.1、HTTP2 比对
TCP通道复用问题
- HTTP/1 一个TCP链接上
只能有一个
请求/响应。
每次浏览器(C)与服务端(S)完成请求处理以后,TCP 链接就会断开
- HTTP/1.1 一个 TCP 链接
可以复用
,再完成一个可以继续下一个
增加了长链接。keep-alive
来开启长链接。也就是说完成请求处理以后 HTTP 连接会维持一段时间,这样在这段时间内如果有新的请求就能够直接传输而不需要再次进行 TCP 建立连接了。
- HTTP2 不需要等待,可以发送
多个
引入了优先级、帧(Frame)、切块等概念。
课外话
TCP 协议通过慢启动机制、拥塞避免机制、加速递减机制、快重传和快恢复机制来共同实现拥塞控制。
HTTP2 与 HTTP1.1
新建了个域名,开启了 HTTP2
TCP
TCP 特性:可靠(知道接收方是否已接收)。对应 UDP(不可靠)。
接收方未收到时,需要有重发机制。但是如果本来就是因为接收方负载过高,那么就会造成网络拥堵、甚至导致把接收方打挂。
这个时候 TCP 要拥有控制流量的办法。防止大量数据过来等待接收。
1988年,Van Jacobson 和 Michael J.Karels 撰文描述了解决问题的几种算法:慢启动、拥塞预防、快速重发和快速恢复。这几种算法被写进了 TCP 规范。
TCP 拥塞窗口
当网络的负载超过了能处理的极限时,就会造成网络拥塞。
TCP 通过动态维护窗口的大小实现以最大负载来传输数据。有两种问题,网络问题,接收方问题。
发送方维护两个窗口:准许窗口(接收方允许的最大字节数)和拥塞窗口(Congestion Window) (发送方传递的字节数量)。最终发送的字节数量是两个窗口的最小值。
TCP 的慢启动机制
当连接建好时,发送方将拥塞窗口初始化为1,然后开始发送数据段。
如果数据段在定时器过期之前被确认,则将拥塞窗口的字节数翻倍(因为是翻倍,所以拥塞窗口会呈指数级增长,直到超时不被确认或者达到接收方窗口限制)。
如果数据段在定时器过期之前没有被确认,则认为网络拥塞。这个时候发送的字节数会减半(阈值也会变化),这个时候还有个阈值的逻辑。
这个算法被称为慢启动算法 ( Slow Start)
当 拥塞窗口 < 阈值 时,使用慢启动算法
当 拥塞窗口 > 阈值 时,使用拥塞避免算法
当 拥塞窗口 = 阈值时,既可以使用慢启动算法,也可时使用拥塞避免算法。
拥塞避免算法
拥塞避免算法的思路是让拥塞窗口缓慢地增大,呈线性增长,即每完成一次,拥塞窗口增加1。