高性能的二进制消息协议-HTTP/2

多路复用 (Multiplexing)

多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。 众所周知 ,在 HTTP/1.1 协议中 「浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超 过限制数目的请求会被阻塞」。下图总结了不同浏览器对该限制的数目。 faedeb3dae59455f6520d6a5dbf436e5_r.png

这也是为何一些站点会有多个静态资源 CDN 域名的原因之一,拿 Twitter 为例,http://twimg.com,目 的就是变相的解决浏览器针对同一域名的请求限制阻塞问题。

而 HTTP/2 的多路复用(Multiplexing) 则允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。 b1e608ddb7493608efea3e76912aabe1_720w.jpg

因此 HTTP/2 可以很容易的去实现多流并行而不用依赖建立多个 TCP 连接,HTTP/2 把 HTTP 协议通信的 基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息。并行地在同一个 TCP 连接上双向交换消 息。

二进制分帧

由于Http1.0 报文Header一般会携带"User Agent""Cookie""Accept""Server"等许多固定的头字段,多达几百字节甚至上千字节,但Body却经常只有几十字节(比如GET请求、 204/301/304响应)。Header里携带的内容过大,在一定程度上增加了传输的成本。

906e22193e61cd561325d93aae0f1e07_720w.jpg

在二进制分帧层中, HTTP/2 会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码 ,其中 HTTP1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到DATA frame 里面。在过去, HTTP 性能优化的关键并不在于高带宽,而是低延迟

总结:

  • 单连接多资源的方式,减少服务端的链接压力,内存占用更少,连接吞吐量更大
  • 由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快

消息传递方式

最小的消息单元为帧,是消息的切片,传输时可以乱序,可以组装。frame组成逻辑上的消息,即request和response。同一个TCP连接上有很多双向流供frame流通。注意,所有的通信都在同一个TCP连接上进行。

1596164-20190502223245069-1174500015.png 1596164-20190502223325217-1328790746.png

首部压缩(Header Compression)

HTTP/1.1并不支持 HTTP 首部压缩,为此 SPDY 和 HTTP/2 应运而生, SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法。 c41c386f03b41f149a53fb17f520dd8d_720w.png 1596164-20190502223350409-785727102.png

服务端推送(Server Push)

服务端推送是一种在客户端请求之前发送数据的机制。在 HTTP/2 中,服务器可以对客户端的一个请求发送多个响应。Server Push 让 HTTP1.x 时代使用内嵌资源的优化手段变得没有意义;服务端推给服务端可以加快网页加载的速度。

1596164-20190502223325217-1328790746.png 服务器推送也有一个很麻烦的问题。所要推送的资源文件,如果浏览器已经有缓存,推送就是浪费带宽。即使推送的文件版本更新,浏览器也会优先使用本地缓存。 1249-20181219132932291-1505004412.png 可以看出,启用HTTP/2后性能并未大幅度提升,所以在使用HTTP/2还是谨慎一些,如果使用不当,反而会使性能下降。

缺点

HTTP/2只支持在https协议

使用HTTPS的话,还需要使用TLS协议进行安全传输,而使用TLS也需要一个握手过程,这样就需要有两个握手延迟过程:

  • 在建立TCP连接的时候,需要和服务器进行三次握手来确认连接成功,也就是说需要在消耗完1.5个RTT之后才能进行数据传输。

  • 进行TLS连接,TLS有两个版本——TLS1.2和TLS1.3,每个版本建立连接所花的时间不同,大致是需要1~2个RTT。

总之,在传输数据之前,我们需要花掉 3~4 个 RTT。

TCP的队头阻塞并没有彻底解决

多个请求是跑在一个TCP管道中的。但当出现了丢包时,HTTP/2 的表现反倒不如 HTTP/1 了。因为TCP为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP连接中的所有请求(如下图)。而对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。

p.png

HTTP/3

Google 在推SPDY的时候就已经意识到了这些问题,于是就另起炉灶搞了一个基于 UDP 协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。而这个“HTTP over QUIC”就是HTTP协议的下一个大版本,HTTP/3。它在HTTP/2的基础上又实现了质的飞跃,真正“完美”地解决了“队头阻塞”问题。 p (1).png QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,接下来我们重点介绍几个QUIC新功能。不过HTTP/3目前还处于草案阶段,正式发布前可能会有变动,所以本文尽量不涉及那些不稳定的细节。

Nginx支持Http2.0

添加http_ssl_module 组件

./configure \
--user=www \
--group=www \
--prefix=/home/nginx-1.16.0 \
--with-http_ssl_module \
--with-http_v2_module \
--with-openssl=/home/nginx-1.16.0/openssl-1.1.0e \
--with-pcre=/home/nginx-1.16.0/pcre-8.37 \
--with-zlib=/home/nginx-1.16.0/zlib-1.2.11 \
--with-http_stub_status_module \
--with-threads

安装

make && make install

配置nginx.conf

#个人博客
server {
	 listen 443 ssl http2;
	 server_name www.n5x.cn;
	 ssl_certificate ssl/1_n5x.cn_bundle.crt; 
	 #私钥文件名称
	 ssl_certificate_key ssl/2_n5x.cn.key; 
	 ssl_session_timeout 5m;
	 #请按照以下协议配置
	 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
	 #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
	 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
	 ssl_prefer_server_ciphers on;
	 location / {
		proxy_pass  http://mysvrblog;
	 }
}

微信截图_20210912201917.png


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!