HTTP/2学习笔记

前言

HTTP 协议(Hyper Text Transfer Protocol)和 TCP/IP 协议族内的其他协议相同,用于客户端和服务器之间的通信。
从1997年发布了HTTP1.1直到2015年,HTTP1.1都是主流的版本,但是随着网络的发展HTTP1.1的一些局限性逐渐暴露出来:队首阻塞问题、首部没有压缩增加延迟以及数据非强制压缩等。
2009年,Google开发了SPDY协议,用于增强HTTP协议,该协议得到了多数浏览器厂商的支持。  2015年IEFT通过对SPDY协议标准化推出了HTTP/2,其主要目标是改进传输性能,实现低延迟和高吞吐量,并且与 HTTP 1.1 完全语义兼容。
HTTP发展史
HTTP/2主要有一下几个新特性:
  • 二进制分帧
  • 请求优先级
  • 多路复用
  • 流量控制
  • 首部压缩
  • 服务器推送

二进制分帧

HTTP/2 所有性能增强的核心,就是引入了二进制分帧层,之前HTTP 1.x在应用层以纯文本的形式进行通信,以换行符作为分割。HTTP/2为了更方便进行一些性能优化,将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。
二进制分帧

帧、消息和流

HTTP/2引入了几个新概念:
  • 帧 HTTP/2通信的最小单位,包括帧首部、流标识符、优先值和帧净荷等
  • 消息 消息是指逻辑上的HTTP消息(请求/响应)。一系列数据帧组成了一个完整的消息。比如一系列DATA帧和一个HEADERS帧组成了请求消息
  • 流 流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。每个流都可以带有一个31 比特的优先值,服务器可以根据流的优先级,控制资源分配
三者的关系是:所有通信都在一个 TCP 连接上完成,此连接可以承载任意数量的双向数据流。每个数据流都有一个唯一的标识符和可选的优先级信息,用于承载双向消息。每条消息都是一条逻辑 HTTP 消息(例如请求或响应),包含一个或多个帧。
帧、消息和流关系

帧类型

根据帧的作用可以将帧分为以下几个类型:
  • DATA:用于传输HTTP消息体;
  • HEADERS:用于传输首部字段;
  • SETTINGS:用于约定客户端和服务端的配置数据。比如设置初识的双向流量控制窗口大小;
  • WINDOW_UPDATE:用于调整个别流或个别连接的流量
  • PRIORITY: 用于指定或重新指定引用资源的优先级。
  • RST_STREAM: 用于通知流的非正常终止。
  • PUSH_ PROMISE: 服务端推送许可。
  • PING: 用于计算往返时间,执行“ 活性” 检活。
  • GOAWAY: 用于通知对端停止在当前连接中创建流。

帧格式

0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | R |     Length (14)           |   Type (8)    |   Flags (8)   |
 +-+-+-----------+---------------+-------------------------------+
 |R|                 Stream Identifier (31)                      |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+
  • R : 保留的2位字段。这些字节的语义是未定义的,并且在发送的时候必须保持未设置(0),接收的时候必须被忽略此字段。
  • Length : 14位无符号整数的帧主体长度。8字节长度的帧报头信息不计算在此内,主体最大可能长度为2^14-1(16383)字节,整个帧(包括首部)的最大长度是最大的帧长度是16391字节。
  • Type : 帧的8位类型。帧类型定义了剩余的帧报头和帧主体将如何被解释。具体实现必须在收到未知帧类型(任何未在文档中定义的帧)时作为连接错误中的类型协议错误(PROTOCOL_ERROR)处理。
  • Flags : 为帧类型保留的8字节字段有具体的布尔标识。 标识针对确定的帧类型赋予特定的语义。确定帧类型定义语义以外的标示必须被忽略,并且必须在发送的时候保留未设置(0)。
  • R : 1位的保留字段。这个字段的语义未设置并且必须在发送的时候保持未设置(0),在接受的时候必须被忽略。
  • Stream Identifier : 31字节的流标识符,唯一标识HTTP/2的流。0是保留的,标明帧是与连接相关作为一个整体而不是一个单独的流。

请求优先级

HTTP/2中每个数据流都可以有一个关联的权重和依赖关系(根据帧类型为PRIORITY标识),这个可以标识资源优先级,服务器可以根据这个决定资源分配(不是强制),可以向每个数据流分配一个介于 1 至 256 之间的整数作为权重。
每个数据流与其他数据流之间可以存在显式依赖关系,依赖关系通过将另一个数据流的唯一标识符作为父项引用进行声明;如果忽略标识符,相应数据流将依赖于“根数据流”。声明数据流依赖关系指出,应尽可能先向父数据流分配资源,然后再向其依赖项分配资源。
权重和依赖关系

上图中流A和B没有依赖关系,权重分别为12和4,则A和B获取资源的比例为3/4、1/4;C依赖于D,则D需要等待C后分配资源。

多路复用

在 HTTP/1.x 中,如果客户端要想发起多个并行请求以提升性能,则必须使用多个 TCP 连接,HTTP2.0 基于二进制分帧层,可以在共享TCP连接的基础上,交错并行的发送请求和响应,互不影响,解决了 HTTP/1.x 中存在的队首阻塞问题,也消除了并行处理和发送请求及响应时对多个连接的依赖。
多路复用

流控制

流控制是一种阻止发送方向接收方发送大量数据的机制,以免超出后者的需求或处理能力
  • 具有方向性
  • 基于信用
  • 无法停止
  • 逐越点控制

首部压缩

在 HTTP/1.x 中,此元数据始终以纯文本形式,通常会给每个传输增加 500–800 字节的开销。如果使用 HTTP Cookie,增加的开销有时会达到上千字节。HTTP/2 使用 HPACK 压缩格式压缩请求和响应头部,HPACK 压缩上下文包含一个静态表和一个动态表:
静态字典在规范中定义,并提供了一个包含所有连接都可能使用的常用 HTTP 标头字段(例如,有效标头名称)的列表;
动态字典最初为空,将根据在特定连接内交换的值进行更新(Huffman Coding:用较少的字节表示较多的数据)动态字典上下文有关,需要为每个 HTTP/2 连接维护不同的字典。
字典

服务器推送

所有服务器推送数据流都由 PUSH_PROMISE 帧发起,表明了服务器向客户端推送所述资源的意图,并且需要先于请求推送资源的响应数据传输。推送资源可以:由客户端缓存、在不同页面之间重用、与其他资源一起复用、由服务器设定优先级以及被客户端拒绝。
服务器推送

浏览器对HTTP/2的支持

下图是Akamai公司建立的一个官方演示,用来说明HTTP2.0相比HTTP1.1在性能上的提升,同时请求379张图片,根据Load time可以看出HTTP2在性能上的优势。
性能比较
HTTP/2的支持情况如下图,可以看到大多数浏览器支持了HTTP/2
HTTP/2支持

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构师进阶

SpringBoot整合Swagger测试api构建

Swagger是什么:THE WORLD’S MOST POPULAR API TOOLING

13540
来自专栏原创分享

nginx0.1.0之http模块初始化源码分析(3)

我们继续分析ngx_http_block函数的代码,指令解析完,继续执行各子模块的钩子函数。

11220
来自专栏finleyMa

Valet 使用 link 命令自定义站点

如果你正在使用mac电脑,并且经常需要在本地部署一些站点,又讨厌频繁的修改服务器配置文件。 强烈推荐使用Valet Valet是一套包含了Nginx和Dns...

23830
来自专栏黑光技术

windows10下使用dockerfile制作镜像

其实操作系统没有关系,主要还是Dockerfile的编写和执行,过程来说比较简单。

1K20
来自专栏盟主来了

19.2.16日报:script的文本解码流程

起源是https://zhitongche.taobao.com/ 有个url(g.alicdn.com/kissy/k/1.4.4/seed.js)老是解码错...

12530
来自专栏云时之间

计算机网络自学笔记:多路复用与多路分解

本文讨论传输层的多路复用与多路分解,也就是将网络层所提供的主机到主机交付服务扩展到为在主机上运行的应用程序所提供的进程到进程交付服务。

16320
来自专栏原创分享

nginx0.1.0之http模块初始化源码分析(5)

继续http模块的分析,这次分析的是init_module钩子函数的执行。http模块各子模块的init_module钩子主要做的事情是两个,一个就是注册pha...

11820
来自专栏smy

apt-get软件包管理命令 和 apt-key命令

所有基于Debian的发行都使用这个包管理系统。deb包可以把一个应用的文件包在一起,大体就如同Windows上的安装文件。

68030
来自专栏原创分享

nginx0.1.0之http模块初始化源码分析(2)

本文讲解http各个模块create_srv_conf和create_loc_conf钩子,还有指令的解析。 各模块的create_srv_conf和creat...

10050
来自专栏cmazxiaoma的架构师之路

SpringBoot集成Hystrix

当访问http://localhost:8082/hystrix1/test1抛出异常,服务降级返回fail1。 当访问http://localhost:80...

86650

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励