HTTP / 2

ops/2025/1/22 9:43:04/
http://www.w3.org/2000/svg" style="display: none;">

序言

 在之前的文章中我们介绍过了 HTTP/1.1 协议,现在再来认识一下迭代版本 2。了解比起 1.1 版本,后面的版本改进在哪里,特点在哪里?话不多说,开始吧⭐️!


一、 HTTP / 1.1 存在的问题

 很多时候新的版本的产生都是需要解决老的版本存在的问题,HTTP / 1.1 存在的问题如下:

头部字段过大且重复
 如果大家抓过包的话,就很能直观的感受这句话。HTTP / 1.1 的头部携带着数据量在有时候会很大,特别是 CookiesUser-Agent 的体量,让大家直观感受一下:

Cookie:
Hm_lvt_ab984c6961d35319708c19c75e093eee=1737127750; Hm_lpvt_ab984c6961d35319708c19c75e093eee=1737127750; HMACCOUNT=8DE7CD8295FF210E; UM_distinctid=19474e1e9808f-0fac1ea52408b5-4c657b58-190140-19474e1e9811325

User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0

因为 HTTP 是无状态的,所以说每次传输数据的时候都需要带上,这就会造成报文体量的增加。

响应队头阻塞
 HTTP / 1.1 为了提升速度,支持同时发送多个请求。但是不管你同时发多少请求,我都会优先处理先到达的,只有第一个请求响应处理完成之后才回去处理之后的请求。这样的话,如果第一个请求的数据特别大,那好,你后面的人全给我等着,这就是队头阻塞。

在这里列举一个餐馆的例子(来自于知乎,特别形象,理解这个就很好理解 HTTP 2 的并发是咋回事):一个餐厅同时可以容纳多个客人(请求),但是餐厅每次会将先来客人的菜上齐了才会取准备下一桌,如果前面一桌的才特别多,那后面的人只有干等着。

被动传输数据
 在 HTTP / 1.1 中 只有客户端向服务器请求数据,服务器不能向客户端主动推送数据。如果一个页面需要渲染的内容很多,需要请求较多数据,只能客户端主动请求,服务器不能主动的推送。


二、 HTTP / 2 的新特性

1. 二进制格式传输数据

 在 HTTP / 1.1 的协议是使用文本的格式传输数据,但在 HTTP / 2 采用了二进制的格式传输数据,这样提高了 数据处理效率 以及 数据传输效率
 数据处理效率,我们的机器本身只能识别并运算二进制的数据,使用文本传输的话还需要对数据进行解析机器才能够直接使用,但是使用二进制传输就省去了这一过程。
 数据传输效率,就拿一个整数 123456 示例:

  • 在文本中,需要使用 6 个字节表示
  • 在二进制中,一个整数类型只需要 4 字节

这不就节约了传输成本,增加了传输效率吗。
 在 HTTP / 1.1 中,我们的一个请求对应一个请求报文,一个响应对应一个响应报文,这是在应用层传输的基本单位。但是 HTTP / 2 的话就不一样了,传输的基本单位是一个 (大小默认是 16 KB),当我们数据太大时会被分为多个帧。

2. 头部压缩(HPACK)

 在 HTTP / 1.1 中,每个 HTTP 请求和响应都会携带头部数据,而这些头部数据大多数情况下是重复的。例如,许多请求和响应都会重复包含相同的字段,如 User-Agent、Host、Accept-Encoding 等。
 HTTP / 2 使用了 HPACKHEAD PACK 把头打包)的方式来压缩头部信息:

  1. 静态表(Static Table):
  • HPACK 使用一个静态表来存储常见的 HTTP 头部字段及其值(总共 61 条)。静态表的内容是固定的,所有 HTTP/2 实现都共享这一表:
    https://i-blog.csdnimg.cn/direct/23a3b8767ffd4c7db7c7a97b58a2bed1.png" alt="在这里插入图片描述" />
  • 可以发现每一个字段都对应了一个 index,在压缩时,HPACK 会使用这个索引值来代替字段名,从而减少传输的字节数,效率是很客观的
  1. 动态表(Dynamic Table):
  • 动态表用来存储当前连接中未出现在静态表的头部字段信息
  • 当该新的头部字段发送时会记录下来,当下一次使用到时就可以使用索引

3. 服务器推送(Server Push)

 是的,服务器也能主动的给我们的客户端推送数据了。就比如下面的场景,当浏览器请求一个 HTML 页面时,也许这个页面还需要各种图片,css等数据。原来只能浏览器主动的请求,服务器才会被动的给我们。现在的话,服务器知道我们还缺什么,直接主动的推送给我们。
 这样的话减少了客户端请求的次数,提升了页面渲染的效率。

4. 并发传输数据(多路复用)

 最重要的特性来啦!但是在开始之前,我想先给大家接着列举餐馆的例子。让大家粗俗的目标他的大致原理,这样也许就更能好好的理解。

HTTP / 2 开的餐馆,也可以同时接纳许多客人,但是为了照顾每一位客人的感受,避免等待太多的时间。他选择了交替的给每一桌上菜,这样后来的客人不要等着前面的吃完了才轮着他。

 首先我们先理解 HTTP / 2 中新增的 stream 流 的概念,流使得同一个连接可以同时并行处理多个请求和响应,而不必等待某个请求的处理完成才能开始下一个请求。
 一个流当中可以传输多个信息,一个信息由一个或多个帧组成,所以一个流中包含了多个帧。我们现在来看图说话:
https://i-blog.csdnimg.cn/direct/b3dcf7b1e1dc410ca0796d9f5cc5942e.png" alt="在这里插入图片描述" />
这是 HTTP / 1.1,熟悉的队头阻塞。现在来看看 HTTP / 2,是如何解决的:
https://i-blog.csdnimg.cn/direct/221f7643f9a94c058bf7dbe812b9e5bb.png" alt="在这里插入图片描述" />
不同的流可以交替的发送数据,因为每一个帧都会携带 stream 的 id,所以到客户端之后数据会组装成一个完整的 stream。


三、HTTP / 2 不足之处

1. TCP 队头阻塞问题

 咦?HTTP / 2不是有效的解决了队头阻塞问题吗?是的,但是他解决的是响应队头阻塞问题,但是我这里说的是 TCP 队头阻塞,比如:
https://i-blog.csdnimg.cn/direct/488197e2ba104ce0babbf6530b072a49.png" alt="在这里插入图片描述" />
TCP 协议,如果前面的数据丢了,后面的数据即使到了也需要等待前面的数据就绪。对于上层来说拿不到数据,不久阻塞了吗?所以说不管你上层怎么设计也离不开下层的坎儿。

HTTP / 3 会采用 UDP 传输数据,就算是数据丢了也不会阻塞。但是回依靠其他技术实现可靠性。

2. 连接建立时间消耗

 HTTP/2 依然基于 TCP 进行连接建立,而 TCP 连接的建立过程需要经过三次握手。尽管 HTTP/2 允许在一个连接中复用多个请求,但每次新连接的建立仍然需要一定的时间。
 在客户端和服务器之间建立新连接时,由于需要执行三次握手过程,连接建立的延迟可能会影响 Web 页面的加载速度,尤其在需要频繁建立连接的场景中。


http://www.ppmy.cn/ops/152167.html

相关文章

计算机的错误计算(二百一十八)

摘要 大模型能确定 sin(2.6^100) 的符号吗?实验表明,大模型给的结论是正确的,但其证明过程是错误百出。大模型的推理实在是不敢恭维。 就同样题目,测试一下另外一个大模型。 例1. 能确定 sin(2.6^100) 的符号吗? 下…

【C++篇】红黑树封装 实现map和set

目录 前言: 一,库中map和set的大致结构 二,模拟实现 2.1,大致框架 2.2,复用红黑树实现insert接口 2.3,迭代器iterator的实现 operator()的实现: operator--()的实现: 对inser…

Python 脚本-显示给定文件的文件信息

目录 Python 代码实现 Python 代码解释 1.导入必要的模块: 2.函数 get_file_info: 3.函数 print_file_info: 4.主函数 main: 5.程序入口: 使用方法 Python 代码实现 import os import stat import sys import…

AI大模型开发—1、百度的千帆大模型调用(文心一言的底层模型,ENRIE等系列)、API文档目的地

文章目录 前言一、千帆大模型平台简介二、百度平台官网初使用1、平台注册和使用2、应用注册 并 申请密钥3、开启千帆大模型 API调用a、API文档b、 前言 本章旨在为读者奉献一份实用的操作指南,深入探索如何高效利用百度千帆大模型平台的卓越功能。我们将从账号注册…

Django多线程爬虫:突破数据抓取瓶颈

Django框架以其高效、安全、可扩展性强等特点,在Web开发领域得到了广泛应用。同时,Python语言的多线程支持和丰富的库也为开发多线程爬虫提供了便利。将Django与多线程技术相结合,不仅可以利用Django的强大功能进行项目管理和数据存储&#x…

强化学习入门--基本概念

强化学习基本概念 grid-world example 这个指的是一个小机器人(agent)在一个网格区域(存在边界),网格中存在需要躲避的格子和目标格子,我们的目的就是找到到达目标格子的最短路径 state 表示智能体相对…

Golang的图形编程应用案例分析与技术深入

Golang的图形编程应用案例分析与技术深入 一、Golang在图形编程中的应用介绍 作为一种高效、简洁的编程语言,近年来在图形编程领域也逐渐展露头角。其并发性能优势和丰富的标准库使得它成为了一个越来越受欢迎的选择。 与传统的图形编程语言相比,Golang具…

网络编程-UDP套接字

文章目录 UDP/TCP协议简介两种协议的联系与区别Socket是什么 UDP的SocketAPIDatagramSocketDatagramPacket 使用UDP模拟通信服务器端客户端测试 完整测试代码 UDP/TCP协议简介 两种协议的联系与区别 TCP和UDP其实是传输层的两个协议的内容, 差别非常大, 对于我们的Java来说, …