探索HTTP/2

文章目录

    • http/1.1
    • http/2
      • 疑惑
    • 探索
      • 1. 连接前言
      • 2. 帧结构
        • 2.1 帧类型 Type
      • 3. 帧详情
        • 3.1 SETTINGS 帧
        • 3.2 WINDOW_UPDATE 帧
        • 3.3 PRIORITY 帧
        • 3.4 HEADERS 帧
        • 3.5 DATA 帧
        • 3.6 PING
        • 3.7 GOAWAY 帧
        • 3.8 RST_STREAM 帧
        • 3.9 PUSH_PROMISE 帧
        • 3.10 CONTINUATION 帧

在这里插入图片描述

你对http2了解多少? 你愿意在你的项目中使用http2吗?为什么?

http/1.1

在这里插入图片描述

从上图可以看到,是一个人在银行排队等待办理一个业务,完成后再去排队办理下一个业务。这就是http/1.1的请求过程。

http/1.1是串行的,也就是说,每个请求都是按顺序进行的,如果前面的请求没有完成,后面的请求就必须等待。

我们无法知道确定之前的顾客在干嘛,可能是在办理业务,也可能是在等待,也可能是在疯狂的聊天直到世界末日。

http/2

在这里插入图片描述

从上图可以看到,是一个人在银行办理多个业务,每个业务都是同时进行的。这就是http/2的请求过程。

http/2是并行的,也就是说,每个请求都是同时进行的,不需要等待前面的请求完成。

疑惑

这样高强度的并行请求,会不会导致服务器压力过大?会不会导致服务器崩溃?

其实不会,http/1.1 并没有榨干TCP协议所能提供的性能。

探索

了解http/2的中的一些细节。

1. 连接前言

在 http/2 中,连接成功后,每个端点都需要发送连接序言作为所使用协议的最终确认。

  • 客户端发送 PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n 作为连接序言
  • 服务器端回应 SETTINGS 帧,帧的内容是服务器端的初始设置,包括最大帧大小,最大并发流数等。

需要注意的是,为了避免不必要的延迟,客户端并不会等待服务器端的回应,而是直接发送请求。

2. 帧结构

在这里插入图片描述

名称长度描述
Length3 字节帧负载的长度(取值范围为 214~224-1 字节),使用SETTINGS 帧可以设置更大值
Type1 字节帧类型
Flags1 字节特定于帧类型的标志
R1 位保留位,无需设置
Stream Identifier31 位流标识符
Frame Payload可变长度帧有效负载,长度在 Length 字段中设置
2.1 帧类型 Type
名称ID描述
DATA0x0传输流的核心内容
HEADERS0x1包含 HTTP 首部,和可选的优先级参数
PRIORITY0x2指示或者更改流的优先级和依赖
RST_STREAM0x3允许一端停止流(通常由于错误导致的)
SETTINGS0x4协商连接级参数
PUSH_PROMISE0x5提示客户端,服务器要推送些东西
PING0x6测试连接可用性和往返时延(RTT)
GOAWAY0x7告诉另一端,当前端已结束
WINDOW_UPDATE0x8协商一端将要接收多少字节(用于流量控制)
CONTINUATION0x9用以扩展 HEADER 数据块
更详细的内容可以参考:

  • Hypertext Transfer Protocol Version 2 (HTTP/2)

3. 帧详情

3.1 SETTINGS 帧

在 http/2 中,请求是通过流的方式进行的。

通常,在发送 连接前言 之后,客户端会发送一个 SETTINGS 帧。这个帧包含了客户端的初始设置,包括最大帧大小,最大并发流数等。

  • 帧大小:默认最大值 2^14 字节 (16,384 字节),如果想要更大的帧大小,可以接收方通过 SETTINGS 帧进行设置。最高可以设置为 2^24-1 字节 (16,777,215 字节)。

示例(十六进制):

00 00 12 04 00 00 00 00 00 00 01 00 01 00 00 00 04 00 02 00 00 00 05 00 00 40 00

这个帧的内容是:

  • 帧长度:18
  • 帧类型:4 (SETTINGS)
  • 标志位:0
  • 流ID:0
  • 帧有效负载:00 01 00 01 00 00 00 04 00 02 00 00 00 05 00 00 40 00



关于R位,是保留位,值为 0。

SETTINGS 帧的有效负载可以设置多个参数,由 16位 类型和 32位 值组成。

 +-------------------------------+|       Identifier (16)         |+-------------------------------+-------------------------------+|                        Value (32)                             |+---------------------------------------------------------------+
类型描述
0x1允许发送方通知远程端点用于解码标头块的标头压缩表的最大大小(以八位位组为单位)。
0x2此设置可用于禁用服务器推送
0x3指示发送方允许的并发流的最大数量
0x4指示发送方用于流级流量控制的初始窗口大小(以八位字节为单位)
0x5指示发送方愿意接收的最大帧有效负载的大小(以八位位组为单位)。
0x6此建议设置通知对等方发送方准备接受的标头列表的最大大小(以八位位组为单位)。
`SETTINGS` 帧的流ID一般为0,表示这是一个连接级的设置,而不是针对某个流的设置。
3.2 WINDOW_UPDATE 帧

在 http/2 中,流量控制是通过 WINDOW_UPDATE 帧来进行的。

WINDOW_UPDATE 帧的有效负载是一个 1 位的 R 位,和 31 位的 增加窗口大小

 +-+-------------------------------------------------------------+|R|              Window Size Increment (31)                     |+-+-------------------------------------------------------------+

帧类型是 0x8,表示这是一个 WINDOW_UPDATE 帧。

帧标志位有两种,分别是 流流控窗口和连接流控窗口,如果是流流控窗口,则指示受影响的流,如果是连接流控窗口,流标识符为 0x0

示例(十六进制):

00 00 04 08 00 00 00 00 00 00 bf 00 01 
3.3 PRIORITY 帧

PRIORITY 帧(帧类型 0x2)用于指示或更改流的优先级和依赖。

使用 `PRIORITY` 帧时,流标识符不能为 `0x0`。

PRIORITY 帧的有效负载是一个 1 位的 E 位,和 31 位的 Stream Dependency,和 8 位的 Weight

 +-+-------------------------------------------------------------+|E|                  Stream Dependency (31)                     |+-+-------------+-----------------------------------------------+|   Weight (8)  |+-+-------------+
  • E 位:如果为 0,则当前流的依赖关系被视为非独占的,这意味着当前流与依赖于同一流的其他流共享依赖关系。如果为 1,则当前流的依赖被认为是独占的,当前流将独占其依赖流,所有其他原本依赖于那个流的流将改为依赖当前流。
  • Stream Dependency:指示当前流的依赖流的标识符。
  • Weight:指示当前流的权重,取值范围为 1~256

示例(十六进制):

00 00 05 02 00 00 00 00 07 00 00 00 00 00
3.4 HEADERS 帧

HEADERS 帧(帧类型 0x1)主要用于传输HTTP请求或响应的头部信息。

HEADERS 帧的有效负载:

类型大小描述
Pad Length8 位用于填充的字节长度(需要有 PADDED 标志)
E1 位指示流依赖性是排他(需要有 Priority 标志)
Stream Dependency31 位该流所依赖的流的 31 位流标识符(需要有 Priority 标志)
Weight8 位用于指示流的权重
Header Block Fragment可变用于存放头部信息
Padding可变用于填充的字节
 +---------------+|Pad Length? (8)|+-+-------------+-----------------------------------------------+|E|                 Stream Dependency? (31)                     |+-+-------------+-----------------------------------------------+|  Weight? (8)  |+-+-------------+-----------------------------------------------+|                   Header Block Fragment (*)                 ...+---------------------------------------------------------------+|                           Padding (*)                       ...+---------------------------------------------------------------+

HEADERS 帧标志:

- `END_STREAM (0x1)`:指示这是流的最后一个帧。
- `END_HEADERS (0x4)`:指示这是头部块的最后一个帧。
- `PADDED (0x8)`:指示这个帧包含了填充字段。
- `PRIORITY (0x20)`:指示这个帧包含了优先级信息。
了解这个帧的结构,可以更好的理解http/2的请求过程。这里可以查看hpack压缩算法,了解更多关于头部块的内容。

https://datatracker.ietf.org/doc/html/rfc7541

3.5 DATA 帧

DATA 帧(帧类型 0x0)用于传输流的核心内容。

+-------------+ |焊盘长度?(8)| +------------------------++--------------------------------- --------------+ | 数据 (*) ... +---------------------------------------- ------------------+ | 填充 (*) ... +---------------------------------------- ------------------+

DATA 帧的有效负载:

  • Pad Length:用于填充的字节长度(需要有 PADDED 标志)。
  • Data:用于存放数据。数据量是帧有效负载减去存在的其他字段的长度后的剩余部分。
  • Padding:用于填充的字节。(填充设置为 0 )

DATA 帧标志:

  • END_STREAM (0x1):指示这是流的最后一个帧。
  • PADDED (0x8):指示这个帧包含了填充字段。

示例(十六进制):

00 00 0c 00 01 00 00 00 0f 7b 22 64 61 79 4e 6f 22 3a 33 30 7d     
3.6 PING

PING 帧(帧类型 0x6)用于测试连接的可用性和往返时延(RTT)。

 +---------------------------------------------------------------+|                                                               ||                      Opaque Data (64)                         ||                                                               |+---------------------------------------------------------------+

PING 帧的有效负载:

  • Opaque Data:用于存放数据。发送者可以包含它选择的任何值并以任何方式使用这些八位字节。

PING 帧标志:

  • ACK (0x1):指示该 PING 帧是 PING 响应。端点必须在 PING 响应中设置此标志。端点不得响应包含此标志的 PING 帧。
流标识符为 `0x0`,表示这是一个连接级的PING帧。否则,视为连接错误。

示例(十六进制):

00 00 08 06 00 00 00 00 00 00 00 00 00 00 00 00 00
3.7 GOAWAY 帧

GOAWAY 帧(帧类型 0x7)用于告诉另一端,当前端已结束。

 +-+-------------------------------------------------------------+|R|                  Last-Stream-ID (31)                        |+-+-------------------------------------------------------------+|                      Error Code (32)                          |+---------------------------------------------------------------+|                  Additional Debug Data (*)                    |+---------------------------------------------------------------+

GOAWAY 帧的有效负载:

  • R:保留位,值为 0
  • Last-Stream-ID:指示发送端认为的最后一个流的标识符。
  • Error Code:用于指示连接关闭的原因。
  • Additional Debug Data:用于存放额外的调试数据。

GOAWAY 帧行为:

  • 发送了GOAWAY帧的一端将忽略所有在GOAWAY帧指定的最后流标识符之后启动的流的帧。
  • 接收GOAWAY帧的一端不应再在该连接上开启新的流,但可以建立新的连接来发起更多的流。
  • 如果接收方在流标识符比GOAWAY帧中指示的更高的流上发送了数据,这些流将不会被处理。接收方可以认为这些流就像从未被创建过一样,并可以在新的连接上重试它们。

示例(十六进制):

00 00 08 07 00 00 00 00 00 00 00 00 00 00 00 00 00
3.8 RST_STREAM 帧

RST_STREAM 帧(帧类型 0x3)用于允许一端停止流(通常由于错误导致的)。

 +---------------------------------------------------------------+|                        Error Code (32)                        |+---------------------------------------------------------------+

RST_STREAM 帧的有效负载:

  • Error Code:用于指示流关闭的原因。
和`GOAWAY`相比,`GOAWAY`针对整个连接,而 `RST_STREAM` 仅针对单个流。 `RST_STREAM` 帧的流标识符不能为 `0x0`。

示例(十六进制):

00 00 04 03 00 00 00 00 03 00 00 00 00
3.9 PUSH_PROMISE 帧

PUSH_PROMISE 帧(帧类型 0x5)用于提前通知对等端点发送方打算发起的流。PUSH_PROMISE 帧包括端点计划创建的流的无符号 31 位标识符以及为流提供附加上下文的一组标头。

 +---------------+|Pad Length? (8)|+-+-------------+-----------------------------------------------+|R|                  Promised Stream ID (31)                     |+-+-------------+-----------------------------------------------+|                   Header Block Fragment (*)                 ...+---------------------------------------------------------------+|                           Padding (*)                       ...+---------------------------------------------------------------+

PUSH_PROMISE 帧的有效负载:

  • Pad Length:用于填充的字节长度(需要有 PADDED 标志)。
  • R:保留位,值为 0
  • Promised Stream ID:指示发送方打算创建的流的标识符。
  • Header Block Fragment:用于存放头部信息。
  • Padding:用于填充的字节。

PUSH_PROMISE 帧标志:

- `END_HEADERS (0x4)`:指示这是头部块的最后一个帧。
- `PADDED (0x8)`:指示这个帧包含了填充字段。

示例(十六进制):

00 00 04 05 04 00 00 00 00 00 00 00 01

PUSH_PROMISE帧允许服务器主动向客户端推送资源,而不需要客户端显式地请求这些资源。这是一种服务器推送技术,旨在减少网页加载时间。通过预先发送客户端将需要的资源,服务器可以显著减少网页完成渲染所需的往返次数(RTTs)。

但是,由于服务器推送可能会导致客户端缓存不一致,因此,服务器推送的资源应该是客户端已经请求过的资源,或者是客户端可能会请求的资源。

3.10 CONTINUATION 帧

CONTINUATION 帧(帧类型 0x9)用于扩展 HEADER 数据块。

 +---------------------------------------------------------------+|                   Header Block Fragment (*)                 ...+---------------------------------------------------------------+

CONTINUATION 帧的有效负载:

  • Header Block Fragment:用于存放头部信息。

CONTINUATION 帧标志:

  • END_HEADERS (0x4):指示这是头部块的最后一个帧。(如果未设置 END_HEADERS 位,则该帧后面必须跟有另一个 CONTINUATION 帧。)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/725679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 EfficientNetV2 实现判别MNIST 手写模型分类

pytorch深度学习项目实战100例 的学习记录 我的环境: 白票大王: google colab 用其他的话,其实实现也行,但是让小白来重环境来开始安装的话,浪费时间 论文速读 EfficientNetV2是由 Google Research,Br…

华为配置智能升级功能升级设备示例

配置智能升级功能升级设备示例 组网图形 图1 配置智能升级功能组网图 背景信息组网需求配置思路前提条件操作步骤操作结果 背景信息 为了方便用户及时了解设备主流运行版本,快速完成升级修复,华为设备支持自动下载、自助升级功能。用户在设备Web网管…

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…

C++ LRU缓存

题目&#xff1a; //构建双向链表的节点结构&#xff08;要有两个构造函数&#xff09; struct Node{int key, val;Node* pre;Node* next;Node():key(0), val(0), pre(nullptr), next(nullptr) {}Node(int _key, int _val): key(_key), val(_val), pre(nullptr), next(nullpt…

windows无界鼠标,多机共享一套键鼠

原因 当前使用一台笔记本和一个台式机。用起来很麻烦。想要找到共享键鼠的方案。找到了无界鼠标这个软件。 安装 在两台电脑上都安装powertoy应用。 https://github.com/microsoft/PowerToys csdn下载 安装完成后找到无界鼠标打开 配置 多台电脑配置相同的key,刷新识别设…

Unity3d调用C++ dll中的函数

一、生成dll 1.新建dll工程 2. 不用管dllmain.cpp&#xff0c;添加自定义Helper.h和Helper.cpp 3.添加要在外部调用的方法 //头文件 #define DLLEXPORT extern "C" __declspec(dllexport) DLLEXPORT int _stdcall Addition(int x, int y); DLLEXPORT int _stdcal…

LeetCode每日一题只 快乐数

目录 题目介绍&#xff1a; 算法原理&#xff1a; 鸽巢原理&#xff1a; 如何找到环里元素&#xff1a; 代码实现&#xff1a; 题目介绍&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a; 我先简单举两个例子&#xff…

python界面开发 - OptionMenu菜单

文章目录 1. python图形界面开发1.1. Python图形界面开发——Tkinter1.2. Python图形界面开发——PyQt1.3. Python图形界面开发——wxPython1.4. Python图形界面开发—— PyGTK&#xff1a;基于GTK1.5. Python图形界面开发—— Kivy1.6. Python图形界面开发——可视化工具1.7. …

ABAQUS软件报价费用 abaqus正版购买价格多少钱?

ABAQUS软件可以完成哪些模拟&#xff1f; ABAQUS软件是一套功能强大的工程模拟的有限元软件&#xff0c;其解决问题的范围从相对简单的线性分析到许多复杂的非线性问题。ABAQUS软件中包含了一套丰富的单元库&#xff0c;可模拟任意几何形状&#xff1b;还包含了各种类型的材料…

【学习笔记】计算机视觉深度学习网络模型

这是本人学习计算机视觉CV领域深度学习模型的学习的一点点学习笔记&#xff0c;很多片子没有完成&#xff0c;可以作为学习的参考~

灵神笔记(1)----动态规划篇

文章目录 介绍动态规划入门&#xff1a;从记忆化搜索到递推打家劫舍递归记忆化递归递推滚动变量 背包0-1 背包递归写法记忆化递归 目标和记忆化搜索递推两个数组一个数组 完全背包记忆化递归搜索 零钱兑换记忆化递归递推 背包问题变形[至多|恰好|至少] 最长公共子序列记忆化搜索…

微信小程序开发系列(二十)·wxml语法·setData()修改对象类型数据、ES6 提供的展开运算符、delete和rest的用法

目录 1. 新增单个、多个属性 1.1 新增单个属性 1.2 新增多个属性 2. 修改单个、多个属性 2.1 修改单个属性 2.2 修改多个属性 3. 优化 3.1 ES6 提供的展开运算符 3.2 Object.assign()将多个对象合并为一个对象 4. 删除单个、多个属性 4.1 删除单个属性 …

搬运机器人助力制造业转型升级

随着传统制造业的转型升级&#xff0c;智能化和多样化成为行业发展的新趋势。在这个过程中&#xff0c;富唯智能搬运机器人作为智能工厂的重要搬运机器人&#xff0c;展现出了卓越的性能和适应性。 它不仅能够应对各种材料、形状和重量的搬运装卸需求&#xff0c;还能与智能物理…

跨链桥的类型总结/相关的名词解释

首先&#xff0c;这是一个会持续更新的文章&#xff0c;我会不断把自己了解到的跨链桥名词解释更新在这里。 跨链桥类型 基于传输方式分类&#xff1a; Lock and Mint&#xff1a;在一条链上锁定资产&#xff0c;在另一条链上铸造等价资产liqidity pool&#xff1a;在不同链…

数字化转型导师坚鹏:金融科技咨询方法论

金融科技咨询方法论 ——方法、做法、演法、心法 课程背景&#xff1a; 数字化转型背景下&#xff0c;很多机构存在以下问题&#xff1a; 不知道先进的金融科技咨询方法论&#xff1f; 不知道如何运作金融科技咨询项目&#xff1f; 不知道如何汇报咨询项目关键成果&…

第五十一回 李逵打死殷天赐 柴进失陷高唐州-AI发展历程和常用框架

朱仝说只要杀了李逵就上梁山&#xff0c;柴进就劝李逵先在庄上住一段时间&#xff0c;先让朱仝、雷横和吴用回了梁山。 李逵在柴进庄上住了一个月&#xff0c;碰到柴进的叔叔柴皇城病重来信叫他去一趟&#xff0c;于是李逵就随着柴进去了高唐州。 柴皇城被殷天锡气死&#xf…

世界级通讯社发稿-法新社海外发稿渠道-大舍传媒

世界级通讯社发稿-法新社海外发稿渠道-大舍传媒 美联社&#xff1a;全球最大的通讯社之一 美联社&#xff08;Associated Press&#xff09;是全球最大的通讯社之一&#xff0c;成立于1846年&#xff0c;总部位于美国纽约。该社拥有一支庞大的全球新闻团队&#xff0c;涵盖了…

mysql8安装配置(最新版)

目录 一、下载mysql8 二、安装mysql8 三、配置mysql 一、下载mysql8 下载链接&#xff1a;https://pan.quark.cn/s/58d9072e51c4 二、安装mysql8 双击msi文件 选择custom 根据所需选择组件 修改安装路径 选中execute&#xff0c;安装&#xff0c;弹出提示安装VS的提示框之后…

MYSQL5.7报1205 - Lock wait timeout exceeded; try restarting transaction

简介 今天使用navicate操作添加时&#xff0c;mysql报错误&#xff0c;错误如下 原因 这个问题的原因是在mysql中产生了事务A&#xff0c;执行了修改的语句&#xff0c;比如&#xff1a; update t1 set aget18 where id1;此时事务并未进行提交&#xff0c;事务B开始运行&am…

自学高效备考2024年AMC10:2000-2023年1250道AMC10真题解析

我们今天继续来随机看5道AMC10真题&#xff0c;以及详细解析&#xff0c;这些题目来自1250道完整的官方历年AMC10真题库。通过系统研究和吃透AMC10的历年真题&#xff0c;参加AMC10的竞赛就能拿到好名次。 即使不参加AMC10竞赛&#xff0c;初中和高中数学一定会学得比较轻松、…