先说结论:HTTP/2的“长连接” = 一个TCP连接 + 多路复用 + 二进制帧 + 流控制 + 持久会话管理
它不只是“连接不断”,更关键的是:在这个长连接上,可以同时并发传输成百上千个请求和响应,互不阻塞!

1、HTTP/2的“长连接”从哪开始?

和HTTP/1.1一样,HTTP/2也是基于TCP协议的。

首先会做的事情和HTTP1.1还是一样的,如:
1、客户端(比如浏览器)和服务器建立TCP连接
2、然后进行TLS握手(如果是HTTPS,可选)

握手完成后,客户端发送一个特殊的“连接前缀”(Connection Preface),如:

"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

它的作用是告诉服务器:
“我要用HTTP/2了,别当成HTTP/1.x处理。”

从此刻起,这个TCP连接就被“升级”为一个HTTP/2连接,并期望长期保持。

2、核心机制:多路复用(Multiplexing),让一个连接“变宽”

(1)、HTTP/1.1的问题(串行排队)

在HTTP/1.1中,即使有keep-alive,也只能:

  • 发请求A → 等响应A → 发请求B → 等响应B → …
  • 或者开6个TCP连接来并发(浪费资源)

这就像是:一条单车道公路,虽然可以供多辆汽车经过,但汽车只能一辆一辆走。

主要问题:

  • 队头阻塞(Head-of-Line Blocking):HTTP/1.1的每个请求必须串行发送(一个接一个),前一个请求未完成时,后续请求必须排队等待。例如,加载网页时,如果图片A的请求卡住了,CSS和JS的请求也会被堵住。
  • 频繁建立连接:为了并行请求,浏览器通常会建立多个TCP连接(如6-8个),但频繁的连接建立和关闭会消耗资源。
(2)、HTTP/2的解决方案:多路复用

HTTP/2把所有请求和响应拆成小块(帧),然后在同一个TCP连接上交错发送。

这就像是: HTTP/2将一个TCP连接想象成一条多车道公路,每个请求和响应是不同的车辆(数据流),它们可以并行行驶(并发传输),互不干扰。

  • 每个请求/响应对(如一个图片请求和它的响应)被分配一个唯一的Stream ID(流标识符),接收方通过这个ID将数据重新组装。
  • 示例:
    • 请求1(图片A):Stream ID = 1
    • 请求2(CSS文件):Stream ID = 3
    • 请求3(JS文件):Stream ID = 5
    • 这些请求的数据帧可以混合在同一个TCP连接上传输,服务器根据Stream ID分别处理。

效果:

  • 单连接并发请求和处理:一个TCP连接可以同时处理数十甚至上百个请求,无需反复建立连接。
  • 消除队头阻塞:即使某个请求的数据包丢失,其他请求的数据仍能继续传输。

3、关键技术:二进制分帧层(Binary Framing Layer)

这是实现多路复用的底层基础。

1、消息结构分层

HTTP/2把通信分成三层:
在这里插入图片描述

2、什么是Frame(帧)?

HTTP/1.1的文本格式问题:

  • HTTP/1.1的请求和响应使用纯文本格式(如GET /index.html HTTP/1.1),解析效率低,且冗余信息多(如重复的头部字段)

HTTP/2的二进制分帧:

  • 数据切片:HTTP/2将每个请求/响应拆分成多个帧(Frame),每个帧是二进制格式的小数据块。

帧有种类:

  • HEADERS帧:存放请求头或响应头(如Host、User-Agent)
  • DATA帧:存放请求体或响应体(如 HTML 内容)。
  • SETTINGS帧:配置参数
  • PING帧:心跳探测
  • RST_STREAM帧:取消某个流
  • GOAWAY帧:优雅关闭连接

每个帧的格式像这样:
在这里插入图片描述
注意:Stream ID它决定了这个帧属于哪个“对话”。

示例:

  • 请求GET /image.jpg会被拆分为:
    1、HEADERS帧(包含Host: example.com等头部)。
    2、DATA帧(可能分多个,传输图片的二进制数据)。
  • 服务器收到后,根据Stream ID和帧类型重组完整请求。

效果:

  • 高效解析:二进制格式比文本解析更快。
  • 减少冗余:通过头部压缩进一步优化。

3、什么是Stream(流)?

  • 一个Stream是客户端和服务器之间的一个独立的双向数据流。
  • 每个HTTP请求/响应对应一个或多个Stream。
  • 每个Stream有唯一ID:
    • 客户端发起的Stream ID是奇数(1, 3, 5…)
    • 服务器发起的(如Server Push)是偶数

举例:

  • 请求首页:Stream 1
  • 请求CSS:Stream 3
  • 请求JS:Stream 5
  • 请求图片:Stream 7

这些Stream的帧可以在同一个TCP连接上混在一起发送:

[DATA, Stream=3]
[HEADERS, Stream=5]
[DATA, Stream=1]
[HEADERS, Stream=7] 
[DATA, Stream=3]

接收方根据Stream ID把属于同一个流的帧重新组装成完整请求或响应。

这就是多路复用:多个请求/响应并行在一个连接上传输,不互相阻塞!

4、头部压缩:减少重复信息的传输

HTTP/1.1的头部冗余:

  • 每次请求都携带大量重复头部(如User-Agent、Cookie),占总传输量的50%以上。

HTTP/2的HPACK压缩:

  • 静态表:预定义常用头部字段(如:method: GET、host),用短编码代替完整字段。
  • 动态表:客户端和服务器维护一个共享的动态表,记录最近传输的头部值(如cookie: abc123),后续请求只需引用索引
  • 示例:
    • 首次请求头部::method: GET, host: example.com, user-agent: Chrome
      • 动态表记录这些值。
    • 后续请求只需发送索引(如:method: 1, host: 2),大幅减少数据量。

效果:

  • 头部体积减少50%-90%,提升传输效率。

5、服务器推送:主动发送资源

传统方式的延迟:

  • 浏览器加载HTML后,发现需要CSS/JS文件,再发起新请求,增加往返延迟。

HTTP/2的服务器推送:

  • 主动推送:服务器在客户端请求HTML时,预测客户端可能需要的资源(如CSS、JS),提前通过PUSH_PROMISE帧推送。
  • 示例:
    • 客户端请求index.html。
    • 服务器响应HTML内容,并通过PUSH_PROMISE推送style.css和script.js。
    • 客户端收到后,直接从本地缓存或推送数据中获取资源,无需额外请求。

效果:

  • 减少请求次数:关键资源提前加载,缩短页面渲染时间。

6、流量控制与优先级:智能分配带宽

流量控制:

  • 滑动窗口机制:客户端和服务器通过WINDOW_UPDATE帧动态调整接收窗口大小,防止缓冲区溢出
  • 示例:客户端通知服务器:“我现在只能接收10KB数据”,服务器按此限制发送。

优先级:

  • 权重分配:每个流(请求)可以设置优先级(1-256),服务器优先处理高权重流。
  • 依赖关系:通过PRIORITY帧 建立流之间的依赖树,例如优先加载HTML再加载图片。

4、HTTP/2是如何“维持”这个长连接的?

1、不主动关闭连接(默认持久)

  • 服务器和客户端都倾向于长期保持这个TCP连接。
  • 不像HTTP/1.1那样容易超时断开。(断开连接时间会比HTTP1.1要长)
  • 浏览器对同一个域名通常只建立1~2个HTTP/2连接,然后一直复用。

2、使用PING帧保活

  • 客户端或服务器可以定时发送PING帧探测连接是否还活着。
  • 对方必须回复一个PONG帧。
  • 这有点像“心跳包”,防止NAT或防火墙误杀空闲连接。

3、流控制(Flow Control)防止压垮对方

  • 每个Stream和整个连接都有流控窗口。
  • 接收方可以告诉发送方:“我只能接收这么多数据,别发太快。”
  • 通过WINDOW_UPDATE帧动态调整。
  • 这让连接更稳定,避免缓冲区溢出。

4、优雅关闭:GOAWAY帧

  • 服务器想关闭连接时,不会直接断开,而是发一个GOAWAY帧。
  • 告诉客户端:“我已经处理到Stream ID=X了,别再发新的请求了。”
  • 已经在传输的请求可以完成,新请求会建立新连接。
  • 这样不会中断用户正在加载的页面。

5、实际效果:一个连接干了以前6个连接的事

在这里插入图片描述

6、什么情况下HTTP/2长连接会断开?

虽然想“一直连着”,但现实中有这些情况会导致断开。
在这里插入图片描述
断开连接后,如果还需要通信,会重新建立一个新的HTTP/2连接,和之前那个没有关系(但Cookie、Token等应用层状态还在)。

7、HTTP1.1和HTTP2对比

在这里插入图片描述

打个比方:

  • HTTP/1.1的长连接:像一条单车道高速公路,车可以一辆接一辆快速开,但不能超车。
  • HTTP/2的长连接:像一条上百车道的超级高速公路,所有车(请求)可以同时开,各走各的道(Stream),互不干扰。

8、总结

HTTP/2的长连接则通过多路复用 + 二进制帧实现多个并行请求复用一个TCP连接,效率更高。

虽然HTTP/2改进了应用层的并发,但如果底层TCP出现丢包,仍可能导致整个连接阻塞(这是HTTP/3使用QUIC和UDP的原因)。
现代浏览器通常对HTTP/1.1使用多个并行连接(如6~8个)来提升并发,而HTTP/2只需一个连接即可达到更高性能。

HTTP2的特性:
在这里插入图片描述

向阳前行,Dare To Be!!!

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

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

相关文章

图解希尔排序C语言实现

1 希尔排序 希尔排序(Shell Sort)是D.L.Shell于1959年提出来的一种排序算法,在这之前排序算法的时间复杂度基本都是O(n),希尔排序算法是突破这个时间复杂度的第一批算法之一。 1.1 基本概念与原理 希尔排序通过将原始列表分割成若…

网络协议——HTTPS协议

目录 一、HTTPS是什么 加密是什么 二、HTTPS的工作过程 (一)对称加密 (二)非对称加密 (三)在非对称加密的基础上,引入证书校验 证书是什么 证书的内容 用证书解决中间人攻击 三、总结 …

React 基础实战:从组件到案例全解析

React 基础实战专栏:从组件到案例全解析 本专栏围绕 React 核心概念(组件、Props、State、生命周期)展开,通过 6个实战案例+核心知识点拆解,帮你掌握 React 基础开发逻辑,每篇聚焦1个实战场景,搭配完整代码与原理讲解,适合 React 入门者巩固基础。 专栏目录 【组件传…

ARM芯片架构之CoreSight Channel Interface 介绍

CoreSight Channel Interface(通道接口)详解1. 概述 Channel Interface 是 ARM CoreSight 架构中用于在不同组件之间传递触发事件的专用接口。它是 Event Interface 的增强版本,支持多通道、双向通信,以及同步与异步两种时钟域连接…

Blender模拟结构光3D Scanner(二)投影仪内参数匹配

关于投影仪外参的设置可参见前一篇文章 Blender模拟结构光3D Scanner(一)外参数匹配-CSDN博客 使用Projectors插件模拟投影仪 Step 1 在Github下载插件(https://github.com/Ocupe/Projectors)。下载zip压缩包即可,无…

synchronized的作用

目录 一、核心作用 二、实现原理:基于"对象锁" 三、使用方式 四、锁的优化 五、优缺点 六、总结 synchronized 是 Java 中用于解决多线程并发安全问题的核心关键字,它的主要作用是实现线程间的同步,确保多个线程在访问共享资…

机试备考笔记 14/31

2025年8月14日 小结:(17号整理14号的笔记,这辈子真是有了w(゚Д゚)w)昨天摔了跤大的,今天好妈妈在家,松弛。省流:6道中等,明天只学了10分钟嘻嘻 目录LeetCode22…

dolphinscheduler中任务输出变量的问题出现ArrayIndexOutOfBoundsException

一段脚本任务如下:ret/data/dolphinscheduler/loadOraTable.sh "yonbip/yonbip10.16.10.69:1521/orcl" "select t.bondcontractno,t.olcunissuemny from yonbip.bond_contract t " "/dmp/biz" "bip" "2025-08-13"…

OpenCv(二)——边界填充、阈值处理

目录 一、边界填充(Border Padding) 1. 常见填充类型及效果 2.代码示例 (1)constant边界填充,填充指定宽度的像素 (2)REFLECT镜像边界填充 (3)REFLECT_101镜像边界…

Leetcode 15 java

今天复习一下翻转二叉树 226. 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2…

嵌入式学习的第四十九天-时钟+EPIT+GPT定时器

一、时钟1.时钟系统基本概念(1)PLL (锁相环, Phase-Locked Loop)作用:PLL是一种反馈控制电路,用于生成稳定的高频时钟信号。它通过将输出时钟与参考时钟进行比较和调整,可以产生比输入参考时钟频率高得多的输出时钟。倍…

Python Sqlalchemy数据库连接

Python Sqlalchemy数据库连接一、连接数据二、模型三、ORM操作一、连接数据 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker# 1. 连接数据库 dbHost postgres://用户名:密码主机:端口/数据库名 engine create_engine(dbHost) # create_engi…

【Node.js】ECMAScript标准 以及 npm安装

目录 一、 ECMAScript标准 - 默认导出和导入 二、ECMAScript标准 - 命名导出和导入 三、包的概念 五、 npm - 安装所有依赖 六、 npm - 全局软件包 Node.js总结 总结不易~ 本章节对我有很大的收获, 希望对你也是!!! 本节素材…

NPM 、 NPX

NPM vs. NPX 简单来说,npm 是一个 node 包管理器,npx 是一个 Node 包执行器。 NPX 是一个 Node 包执行器,该 Node 包可以是本地也可以是远程的。允许开发者在无需安装的情况下执行任意 Node 包。npm 在安装nodejs 就自动带了 npm install -g …

守护品质安全,防伪溯源系统打造全链路信任体系

一、引言在当下这个信息透明、品质至上的时代,防伪溯源已经成为众多品牌保护自身利益、提升消费者信任度的重要手段。为了满足市场上对高效、可靠的防伪溯源查询系统的迫切需求,榕壹云精心打造了一款防伪溯源查询系统。二、项目背景随着商品市场的不断扩…

【完整源码+数据集+部署教程】无人机航拍视角洪水检测与受灾房屋识别图像分割救援指导系统源码和数据集:改进yolo11-DCNV2

背景意义 研究背景与意义 随着全球气候变化的加剧,极端天气事件的频率和强度不断上升,洪水作为一种常见的自然灾害,给人类社会带来了严重的威胁。洪水不仅导致人员伤亡和财产损失,还对基础设施和生态环境造成了深远的影响。因此&a…

C# 结构体与类的区别是什么?

结构体是值类型是储存在栈中独立储存的,数据与数据之间不会相互影响,即使将一个结构体赋值给另外一个结构体也不会相互影响。 类是一个模板,实例出来的对象是独立的不会相互影响,但是将一个对象赋值给另一个对象时 会把指向堆内存中数据的指针赋值给另一个对象.从而发生两个变量…

Redis GEO

Redis GEO 引言 Redis 是一款高性能的键值存储系统,广泛应用于缓存、消息队列等领域。Redis GEO 是 Redis 2.4 版本后新增的一个功能,用于存储地理位置信息。本文将详细介绍 Redis GEO 的概念、使用方法以及应用场景。 什么是 Redis GEO? Redis GEO 是 Redis 的一个模块…

Go从入门到精通系列学习路线规划

Go从入门到精通系列学习路线规划 目录导航 Go从入门到精通系列学习路线规划首页说明 第1篇_Go语言初探_环境搭建与HelloWorld 第2篇_Go语言基础语法_变量常量与数据类型 第3篇_Go语言控制结构_条件判断与循环 第4篇_Go语言函数详解 第5篇_Go语言数据结构详解 第6篇_Go语言结构体…

Grid系统概述

目录 概念及功能 网格对象(Grid Object) 和世界对象(World Object) 工作流程 概念及功能 TrinityCore 的 Grid 系统是一套复杂的地图分区管理机制,其核心目标是通过动态管控游戏世界的区域状态和对象生命周期&#…