Http2升级方案调研
背景
HTTP/2 相比于 HTTP/1.1,可以大幅度提高网页请求响应的性能,HTTP/2对请求机制做了部分优化,能够并发更多的请求,可以提升网页的加载速度,提升用户体验度。
HTTP/1.1 存在的问题:
1、TCP 连接数限制
对于同一个域名,浏览器最多只能同时创建 6~8 个 TCP 连接 (不同浏览器不一样)。如果在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。
2、线头阻塞问题
每个 TCP 连接同时只能处理一个请求 - 响应,浏览器按 FIFO 原则处理请求,如果上一个响应没返回,后续请求 - 响应都会受阻。
3、Header 内容过多
同域名请求下HTTP1.1中的header信息相同点过多,每个请求都需要重新发送一次,没有经过任何压缩和相应的压缩传输优化方案。
HTTP/2 的优点:
1、新的二进制格式
-
HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”:头信息帧和数据帧。
-
二进制协议解析起来更高效、“线上”更紧凑,更重要的是错误更少。
2、多路复用
- HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
- HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
- HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”。
具体如图:
3、HTTP/2 头部压缩(HPack)
HTTP是一个无状态协议,导致每次请求都必须附上所有头信息。所以请求的很多头字段都是重复的,没有经过任何压缩,比如Cookie,一样的内容每次请求都必须附带,这会浪费很多带宽,也影响速度。如图:
HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。
关于HPACK 算法,具体可以参看https://tools.ietf.org/html/rfc7541
具体来说:
-
在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
-
首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
-
每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。
例如下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。
4、服务端推送(Server-Push机制)
在HTTP 1.1里,在同一个 TCP 连接里面,上一个回应(response)发送完了,服务器才能发送下一个,但在HTTP/2里,可以将多个回应一起发送。
HTTP2 还在一定程度上改变了传统的“请求 - 应答”工作模式,服务器不再完全被动地响应请求,也可以新建“流”主动向客户端发送消息。
比如,在浏览器刚请求 HTML 的时候就提前把可能会用到的 JS、CSS 文件发给客户端,减少等待的延迟,这被称为"服务端推送(Server-Push机制)“。
Server-Push 主要是针对资源内联做出的优化,相较于 http/1.1 资源内联的优势:
-
客户端可以缓存推送的资源
-
客户端可以拒收推送过来的资源
-
推送资源可以由不同页面共享
-
服务器可以按照优先级推送资源
具体区别如图::
HTTP/2 的缺点:
1、丢包场景
上文提到 HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。但当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1 了。
因为在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
不过丢包场景在国内访问情况下非常罕见,不足以因此而不去升级HTTP/2
HTTP/2 升级步骤:
1、首先需升级项:http→https、http1.1→http2
2、然后联系OP支持操作升级,后端研发协助。
HTTP/2 升级影响
1、兼容性:向下兼容,即http2兼容http1.X。
2、线上服务:需重启对应服务器,短暂影响线上服务,原则上对已有项目功能不影响。
3、服务返回状态不同:HTTP/2 相比于 HTTP/1.1接口服务返回状态不同,如有前端存在使用”Status Code“状态 200 & ok 判断接口状态的需做修改。