HTTP/2

HTTP/2(简称h2)

《HTTP协议:0.9 -> 1.0 -> 1.1》
《HTTPS》

诞生原因:
HTTP1.1的缺陷——当今的网络环境下,大多数web页面都会关联数十个域名,HTTP/1.1无法在不牺牲速度的情况下适应当今的复杂页面,每新增一个域名都要增加DNS解析耗时TCP连接耗时TLS协商耗时,为了应对这些耗时增加,客户端会对同一个域名开启多个socket,进一步加重了服务器负担

HTTP/1.1的缺点:

  1. 队头堵塞:HTTP 1.1采用了管道,允许一个连接中发送多次请求,但是要求响应必须和请求顺序一致,可能造成队头堵塞
  2. TCP利用率低
  3. 消息首部不支持压缩,严重消耗带宽
  4. 不支持socket优先级的设置

HTTP/2的改进

1.二进制协议

HTTP 1.1headerASCII码,数据体则允许二进制,而HTTP/2则是彻底的二进制协议,headerbody都被称为
二进制协议可以定制特殊的,如果使用文本来实现非常麻烦,而二进制则简单得多。

2.多工

HTTP/2复用TCP连接,支持双向、实时的通信,在一个连接内能发送多个请求或回应,并且不要求按照顺序对应,有效地避免了队头堵塞

值得注意的是,由于HTTP/2采用单一TCP连接,当网络拥塞造成频繁丢包时,TCP协议就会缩减TCP窗口大小,影响HTTP/2的传输效率。

3.数据流

HTTP/2将所有请求/回应的所有数据包,称为一个数据流,每个数据流都有一个独一无二的编号。

  1. 每次发送数据包时,必须标记数据流ID,以区分数据包属于哪个数据流。
  2. 规定客户端的数据流ID一律为奇数,服务器的数据流ID一律为偶数。
  3. 数据流发送到一半时,双方都可以发送信号RST_STREM来取消数据流。这意味着,HTTP/2可以取消某次请求,但不关闭连接,连接可以被后续的请求复用
  4. 数据流还可以设置优先级,优先级越高,服务器越先处理。

4.头信息压缩&头信息表

HTTP是无状态的,每次请求必须带上很多参数,这些参数往往会重复,比如CookieUser Agent,重复的内容占用了带宽,也影响速度。

  1. HTTP/2采用HPACK对头信息进行压缩后再发送。
  2. HTTP/2中,服务器和客户端共同维护一张头信息表,所有字段都会写入并生成一个索引号,每次不再发送相同字段,而是直接发索引。

5.服务器推送

允许服务器在没有收到请求的情况下,主动向客户端推送数据。
服务器推送的对象会被存到浏览器的缓存里。如果服务器决定推送一个对象,会构造一个PUSH_PROMISE帧,如果客户端对PUSH_PROMISE帧中的任何元素不满意,或是缓存中已有此对象,都可以按照拒收原因选择重置这个流(使用RST_STREAM),或发送PROTOCOL_ERROR


HTTP/2 基础概念

1.分层

(1).分帧层

HTTP/2多路复用功能的核心部分,是基于的二进制协议。

目的:传输HTTP

(2).数据层(HTTP层)

传统上被认为是HTTP及其相关数据的部分

2.连接:TCP/IP socket

定义:一个连接就是客户端初始化的一个TCP/IP socket

内容:共同依赖的连接层设置头信息表

3.帧:流ID + HEADER + DATA

数据传输的基本单位,每个上都有一个流ID,表明帧所属的

1
2
3
4
5
6
7
8
9
10
HEADERS         头信息帧
DATA 数据帧
PRIORITY 优先级帧
RST_STREAM 流终止帧
SETTINGS 设置帧
PUSH_PROMISE 服务器推送帧
PING
GOAWAY 连接关闭帧
WINDOW_UPDATE 流量控制帧
CONTINUATION

4.流

连接上的一系列,构成了HTTP/2的请求和响应消息。
同一个连接上可以有多个,可以通过PRIORITY帧为不同的设置不同的优先级,这就是HTTP/2的多工。


HTTP/2 启动 & 运行

参考《阿里云ECS上安装Nginx》,分为两步:

1.下载并安装一张TLS证书

想使用HTTP/2就要先启用HTTPS,这里我们选择Let's Encrypt作为证书,Certbot作为Let's Encrypt的客户端。

服务器上运行如下命令,其中<your web root>是你web服务器的文件目录;<your domain>是你的域名:

1
2
3
4
5
6
7
# 安装Certbot
yum -y install wget
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

# 获取Let's Encrypt证书
./certbot-auto certonly --webroot -w <your web root> -d <your domain>

执行命令后会安装所有需要的包,展示一些需要你输入的问题,最后你的证书和私钥会被放到/etc/letsencrypt/live/<your domain>目录下:

1
2
3
4
privkey.pem     证书私钥
cert.pem 新证书
chain.pem CA证书链
fullchain.pem 包含证书和证书链的文件

2.获取并安装一个支持h2的web服务器,让浏览器和服务器通过h2连接

为了尽可能的简单,没有直接使用Nginx,而是使用nghttp2包下的nghttpd工具。

1
2
3
4
# 安装
yum install -y nghttp2
# 启动
./nghttpd -v -d <webroot> <port> <key> <cert>

其中<webroot>是你web服务器的文件目录,<port>是服务器要监听的端口号,<key>是你生成的私钥privkey.pem路径,<cert>是证书cert.pem路径。如:
./nghttpd -v -d /usr/local/www 8082
/etc/letsencrypt/live/www.dragonbaby308.com/privkey.pem
/etc/letsencrypt/live/www.dragonbaby308.com/cert.pem

然后就可以通过浏览器访问了:


前瞻性发展

快速UDP网络连接(QUIC, Quick UDP Internet Connection)

HTTP/2的一大弱点就是依赖于TCP实现,由于TCP慢启动拥塞控制以及不合理的丢包就缩小发送窗口机制,面对TCP层级的队首阻塞,HTTP/2显得束手无策。
Google开发的QUIC提供了HTTP/2等效的多路复用流控TLS等效的安全机制,以及TCP等效的连接语义、可靠性、拥塞控制。

TCP/IP的发展与UNIX操作系统的普及离不开,UNIX支持TCP/IP协议,由于UNIX工作站盛行,互联网从一开始就是基于TCP/IP构建的。
但是在HTTP/2中我们能够看到,TCP较为保守的一旦网络拥塞就将发送窗口减半的策略,已经影响到了HTTP/2单连接多工的传输方式,所以有人考虑能不能用UDP取代TCP,谷歌就有这方面的研究——QUIC。
但是现有的网络、操作系统都是基于TCP/IP进行构建的,如果全面切换UDP意味着所有底层架构都需要改写以进行支持,代价实在太大,个人认为不太现实。

TLS 1.3

之前版本的TLS新连接至少需要3次往返时延(即三次握手),而TLS 1.3新连接只需要1次往返时延,如果是恢复连接的话,不需要往返时延

往返时延:RTT

-------------本文结束感谢您的阅读-------------

本文标题:HTTP/2

文章作者:DragonBaby308

发布时间:2019年07月18日 - 21:10

最后更新:2019年09月22日 - 10:07

原始链接:http://www.dragonbaby308.com/http2/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%