HTTP/2协议详细介绍

0 摘要

  1. 兼容HTTP1.1

  2. 头部压缩

  3. 二进制帧

  4. 并发传输

  5. 服务器主动推送资源

  6. HTTP2的队头阻塞问题

1 兼容HTTP1.1

HTTP2的优点我们后面会一一列出,但是一个新的东西的升级必须要做到向前兼容才能快速推广,因为只有这样才能减少对用户的影响。

HTTP2对HTTP1.1的兼容体现在哪些方面

  • 协议名依然使用http,加密的依然使用https,浏览器和服务器只需要在幕后自动升级协议,用户并不会感知到协议的变化。

  • HTTP2下层协议依旧是TCP,但把HTTP分成了语法语义两个部分,语义层不做改动(比如请求方法、状态码等都保持不变)

2 头部压缩

HTTP1.1只能对请求体进行压缩,但HTTP2除了对请求体进行压缩还可以对Heder进行压缩。

HTTP2 Header的压缩方式

HPACK算法,HPACK算法主要包含三个部分:

  • 静态字典

  • 动态字典

  • Huffman编码

客户端和服务端会建立维护好静态字典和动态字典,用长度较小的索引号表示重复的字符串,另外一些不固定的变化的value需要通过Huffman进行编码。

静态字典

HTTP2为Head中高频出现的字符串和字段建立了一张静态表,静态表中一共维护了61项,主要包含三项内容:

  • Index:表示索引

  • Header Name:表示字段的名称

  • Header Value:表示索引对应的value

为什么有些Header Value不存在?

有些Head Value不是固定的,这些value需要经过Huffman压缩后在进行发送。

Head的格式

如果Head字段属于静态字典,那么Head的固定格式如下:

 

  • 第一个字节:前两位固定位01,剩余的位用来标识静态表中的Index

  • 第二个字节:首位用来表示是否使用Huffman编码压缩算法,剩余的7位标识value的长度,首位为1表示使用Huffman

  • 剩余的位数:value经过Huffman编码的数据

静态字典表和Huffman编码点击此处

动态表编码

静态表只包含61组数据,不在静态表的头部字符串就需要自行构建动态表,动态表的index从62开始。

使用动态表的前提是必须在同一个连接上,重复传输完全相同的HTTP头部。

动态表编码的缺点

随着HTTP2连接上发送的报文越来越多,动态表里面的数据也会越来越多,会吃掉越来越多的服务器内存资源,因此一般web服务器都会有参数用于限制一个连接上能够传输的请求数量,避免动态表无限增大,请求数量达到限制后会关闭HTTP2连接来释放内存。

HTTP2的头部压缩是通过「静态表 + 动态表 + Huffman编码」一起来实现。

3 二进制帧

HTTP2相比于HTTP1.1使用了二进制进行数据传输,提高了HTTP的传输效率,同时也方便了使用位运算对HTTP数据进行解析。

HTTP2把报文整体划分为两个帧,分别是Headers Frame和DATA Frame。

HTTP2帧结构

 

HTTP2帧结构大体划分为两部分:

  • 9个字节的帧头

  • 帧数据

HTTP2的帧头主要由以下几部分:

  • Length:帧数据的长度

  • Type:帧类型

  • Flag:标志位,用于携带简单的控制信息

  • R:保留位

  • Stream Identifier:流标识符,用来标识该帧属于哪个Stream,接收方可以根据流标识符从乱序的帧中找到找到具有相同Stream ID的帧,然后进行组装

  • Frame Payload:帧数据,存放的是HTTP头部和包体

HTTP2帧类型

HTTP2的帧类型大体分为两种:

  • 数据帧

  • 控制帧

帧类型类型编码用途
数据帧 DATA0x0传输HTTP包体
数据帧 HEADERS0x1传输HTTP头部
数据帧 PRIORITY0x2指定Stream流的优先级
控制帧 RST_STREAM0x3终止Stream流
控制帧 SETTINGS0x4修改连接或者Stream流的配置
控制帧 PUSH_PROMISE0x5服务器推送资源时描述请求的帧
控制帧 PING0x6心跳检测,可以用于计算RTT
控制帧 GOAWAY0x7优雅的终止连接或者通知错误
控制帧 WINDOW_UPDATE0x8实现流量控制
控制帧 CONTINUATION0x9传递较大HTTP头部时持续的帧

4 并发传输

HTTP2的并发传输基于Stream实现的。

为什么需要并发传输?

HTTP1.1中同一个连接中,只有上一个请求和响应被处理后,才能继续处理下一个,也就是如果客户端发送的请求,服务端一直没有响应,客户端无法继续下一个请求,从而导致队头阻塞。

HTTP2如何实现并发传输?

HTTP2通过多个Stream复用一条TCP连接,达到并发效果。

 

  • 1个TCP连接包含一个或多个Stream

  • Stream里面可以包含1个或多个Message,Message对应HTTP1.1的请求或响应,由HTTP的头部和包体组成

  • Message里包含一个多个帧,帧是HTTP2的最小单位

不同Stream的帧是可以乱序发送的,接收方通过帧上的StreamId来区分该帧是由哪个Stream发送。

Stream ID的生成规则

客户端和服务器都可以建立Stream,客户端建立的Stream必须是奇数号,服务器建立的Stream必须是偶数号。

同一个连接中的Stream ID不能复用,必须严格顺序递增,如果StreamID消耗完,会发送一个GOAWAY控制帧关闭TCP连接。

HTTP2并发传输的优点

HTTP2在实现并发时,下层的TCP连接都是同一个,因此避免了TCP握手、慢启动以及TLS的握手过程,减少了耗时。

5 服务器主动推送资源

如何实现推送

服务器在主动推送资源时,会通过PUSH_PROMISE控制帧传输HTTP头部,并通过帧中的Promise Stream Id字段告知客户端接下来会在哪个Stream中发送包体。

6 HTTP2的队头阻塞问题

HTTP2虽然在应用层解决了队头阻塞问题,但由于下层还是使用一个TCP连接,所以HTTP2的队头阻塞问题存在于传输层。

HTTP2是基于TCP协议来传输数据的,TCP是字节流协议,TCP层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给HTTP应用,那么当前字节数据没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到当前字节数据到达时,HTTP2应用层才能从内核中拿到数据,因此假设传输层不稳定,也会导致响应变慢队头阻塞。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值