当前位置: 首页 > news >正文

HTTP协议-3-HTTP/2是如何维持长连接的?

先说结论: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.dtcms.com/a/336646.html

相关文章:

  • JAVA后端开发——Token自动续期机制的必要性
  • 【Linux内核】Linux信号机制
  • 【Linux】五种IO模型
  • JVM学习笔记-----StringTable
  • react 错误边界
  • Python 内置模块 collections 常用工具
  • 【撸靶笔记】第二关:GET -Error based -Intiger based
  • Spring Framework :IoC 容器的原理与实践
  • CW32L011_电机驱动器开发板试用
  • 工作中使用到的时序指标异常检测算法 TRPS 【Temporal Residual Pattern Similarity】和 K-sigma 算法
  • 区块链:数字时代信任基石的构建与创新
  • 25年第十本【金钱心理学】
  • 1. Docker的介绍和安装
  • 洛谷 P2324 [SCOI2005] 骑士精神-提高+/省选-
  • CE桥接MuMu模拟器
  • 计算机网络 Session 劫持 原理和防御措施
  • IC验证 AHB-RAM 项目(一)——项目理解
  • 【leetcode】58. 最后一个单词的长度
  • Python大模型应用开发-核心技术与项目开发
  • 【165页PPT】基于IPD的研发项目管理(附下载方式)
  • vue路由懒加载
  • 数据链路层(1)
  • Linux操作系统软件编程——多线程
  • 基于飞算JavaAI实现高端算法性能优化:从理论到落地的性能跃迁实践
  • C++---迭代器删除元素避免索引混乱
  • 【Golang】:函数和包
  • 因果语义知识图谱如何革新文本预处理
  • os详解,从上面是‘os‘模块?到核心组成和常用函数
  • 智能合约里的 “拒绝服务“ 攻击:让你的合约变成 “死机的手机“
  • 什么是AI Agent(智能体)