CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
HTTP 协议与缓存/课时/HTTP/2 与 HTTP/3
RawBlame
课时目录12 节

HTTP 协议与缓存

  1. 01HTTP 是什么
  2. 02方法与语义
  3. 03状态码
  4. 04请求与响应头
  5. 05HTTPS 与 TLS
  6. 06HTTP 缓存
  7. 07Cookie 与会话
  8. 08CORS
  9. 09REST 与资源设计
  10. 10HTTP/2 与 HTTP/3
  11. 11应用层缓存对照
  12. 12综合练习

HTTP/2 与 HTTP/3

多路复用、QUIC 概念。

25 分钟

HTTP/2 与 HTTP/3

这一课你将能做到

  1. 说明 HTTP/1.1「多开 TCP 连接硬扛并发」与 HTTP/2「单连接多路复用」各自如何解决并发问题,以及 TCP 层队头阻塞为何 h2 没根治
  2. 在 DevTools Network 打开 Protocol 列识别 h2 / h3 / http/1.1,并用 curl --http2 验证站点协议
  3. 列出对日常开发仍重要的三件事:TLS 前提、淘汰域名分片、协议升级不能替代压缩与缓存

为什么要学

打开 /tracks 要拉 HTML、CSS、JS、字体、API——HTTP/1.1 时代靠「每域 6 条 TCP 连接」硬扛,小文件多时握手开销和排队延迟很显眼。HTTP/2 在一条 TLS 连接上交错传多个流,HTTP/3 干脆把传输层换成基于 UDP 的 QUIC。

运维在 Nginx 开了 http2,前端却还在做「域名分片、合并文件」的 1.1 时代优化,收益被互相抵消——理解协议演进才能做对优化决策。面试问「HTTP/2 解决了什么问题、没解决什么」,答出「应用层队头阻塞解决了、TCP 层还在」就是高分答案。

先建立图像

HTTP/1.1 的困境:
  每域约 6 条 TCP,每条同一时刻只能服务一个请求
  → 前一个响应慢,同连接后面的全排队(队头阻塞)
  → 小文件多时,握手/慢启动开销显眼

HTTP/2 的解法:
  一条(通常 TLS)连接上多个 stream 并行交错
  二进制分帧 + HPACK 头压缩 + 优先级
  浏览器侧几乎总要求 HTTPS

HTTP/3 的再解法:
  应用语义不变,传输层换 QUIC(UDP)
  → 单个流丢包不再拖死整条连接(流级独立恢复)
  → 换 Wi-Fi/切 4G 连接迁移不断线

对比表:

特性HTTP/1.1HTTP/2HTTP/3
并发方式多条 TCP 凑单连接多 streamQUIC 上多流
报文格式文本二进制分帧二进制分帧
头部明文重复传输HPACK 压缩QPACK 压缩
传输层TCPTCPQUIC/UDP
DevTools 显示http/1.1h2h3

跟着做

步骤 1:打开 Protocol 列,看看你天天访问的站在跑什么

  1. 打开 https://coderoadmap.cn/tracks
  2. F12 → Network → 表头右键 → 勾选 Protocol 列
  3. Ctrl+Shift+R 硬刷新,逐行看 document、静态资源、api/tracks 各自的协议

应看到:现代站点主流是 h2;第三方脚本可能还是 http/1.1(对方服务器没开);有 CDN 且支持时可能出现 h3。

步骤 2:curl 验证与强制协议

# 请求使用 HTTP/2(服务器需支持,否则自动回落 1.1)
curl -I --http2 https://coderoadmap.cn

# 看协商过程:ALPN 里应出现 h2 与 http/1.1 两个候选
curl -v --http2 -o NUL https://coderoadmap.cn 2>&1 | findstr /i "ALPN HTTP/2"
# Linux/macOS:curl -v --http2 -o /dev/null https://coderoadmap.cn 2>&1 | grep -iE "ALPN|HTTP/2"

# 强制只接受 HTTP/2,不支持就报错
curl -sI --http2-prior-knowledge https://coderoadmap.cn | head -n 1

若线上 --http2 只得到 HTTP/1.1 200,说明 Nginx/CDN 没启用 h2 或中间链路降级了。

步骤 3:给本机 Nginx 开 http2(可实操)

修改 Nginx 站点配置:

server {
    listen 443 ssl http2;          # 1.25.1+ 也可写 listen 443 ssl; http2 on;
    server_name localhost;
    ssl_certificate     /path/to/cert.pem;    # 沿用 HTTPS 课的自签证书
    ssl_certificate_key /path/to/key.pem;

    location /api/ {
        proxy_pass http://127.0.0.1:8080;
    }
}
nginx -t && nginx -s reload
curl -sI --http2 https://localhost/api/hello -k | head -n 1
# 期望输出:HTTP/2 200

浏览器访问同样页面,Protocol 列会显示 h2——你亲手完成了一次协议升级。

步骤 4:数请求,体会多路复用的价值

在 Network 底部看「N requests / X transferred」;瀑布图里同域请求的彩色条明显并行起步,不再是一条等一条的阶梯。对比实验:找一个还在 1.1 的老站(或临时关掉 http2 on;),同样刷新——瀑布图呈串行长队。把两张截图存进笔记。

步骤 5:淘汰过时优化口诀

1.1 时代的优化h2/h3 时代
域名分片凑 6 连接停止:破坏单连接复用,还多几次握手
拼命合并 JS/CSS 成巨型文件改为合理拆包:并行传输让小模块不再昂贵,但过大仍不利缓存
全部内联 CSS/JS权衡:外链可独立长缓存(缓存课),h2 下内联收益下降
精灵图(Sprite)逐图请求 + 缓存更灵活

仍然重要的:压缩(gzip/br)、图片体积、HTTP 缓存、CDN——协议更快不等于可以不裁剪数据。

步骤 6:Server Push 的现状

HTTP/2 Server Push 曾被寄予厚望(服务器猜你要什么,提前推),实战命中率低、易推成重复资源,Chrome 已移除支持。现代替代:<link rel=preload>(页面自己声明关键资源)、HTTP 缓存、正确的优先级。新项目别把 Push 当必选项,面试答「已基本弃用、被 preload 取代」即可。

步骤 7:伪头与业务代码的分工

HTTP/2 线上报文用 :method、:path、:authority、:scheme 伪头承载请求要素:

stream A  :method GET   :path /tracks
stream B  :method GET   :path /_next/static/chunk-abc.js
stream C  :method GET   :path /api/tracks
(三条 stream 交错在同一条 h2 连接里飞)

DevTools 的 Headers 视图已翻译回熟悉的 Request Method/URL,curl -v 时可瞥见原文。业务代码继续按「方法 + 路径 + 状态码」思考——分帧是传输层的事,Controller 里不存在「操作伪头」这种需求。

排错口诀:若 Protocol 全是 http/1.1,先查 Nginx listen ... http2(或 http2 on;),再查是否被公司代理/老 CDN 降级,而不是改业务代码。

讲清楚要点

  1. 因为浏览器对 HTTP/2 几乎总走 TLS,所以 h2 是 HTTPS 课的延伸而非平行知识——先有证书,再谈协议升级;明文 h2c 浏览器不用。
  2. 因为 h2 的多路复用仍在一条 TCP 上,所以一个包丢失会让 TCP 层重传阻塞所有 stream——这是「h2 在高丢包网络可能不如多条 1.1 连接」的理论根源,h3/QUIC 用流级独立恢复解决。
  3. 因为 HPACK 压缩重复头,所以大量小 API 请求(重复 UA/Cookie)更省——但仍别无脑塞巨型 Cookie,压缩不改变「每请求都带全量头」的事实。
  4. 因为协议快不等于业务快,所以慢 TTFB 仍要查 SQL/缓存/逻辑——Network 的 Timing 分段看:DNS/TLS/TTFB/下载,优化手段完全不同。
  5. 因为中间盒可能禁 UDP/443,所以 HTTP/3 不一定处处可用——主流做法是 h3 与 h2 并行advertise,客户端按可达性选择;能稳定 h2 已是巨大收益。
  6. 因为应用语义未变,所以方法/状态码/头知识全部保值——升级传输层不需要重学 REST;本 track 前几课的内容在 h2/h3 下一字不改地成立。

你可能会懵的地方

  1. 都说 h2 消灭了队头阻塞,为什么面试官说没消灭? h2 消灭的是应用层「一连接一请求」的排队;但所有 stream 仍共享一条 TCP,TCP 只认字节流、不知道 stream 边界,丢一个包就得停流等重传——这是 TCP 层队头阻塞。h3 把传输换成 QUIC(流之间独立恢复)才真正根治。

  2. 为什么我电脑上显示的还是 http/1.1? 依次排查:Nginx 没配 http2;中间有公司 SSL 检查设备或代理降级;用了不支持 h2 的老客户端;CDN 未开启。以 DevTools Protocol 列为准,别信文档口头承诺。

  3. HTTP/3 一定比 h2 快吗? 弱网、高丢包、移动切换场景优势明显(0-RTT 恢复、连接迁移);稳定低丢包宽带上与 h2 差距不大。一切以实测为准,但开启成本已很低(Nginx 1.25+ 一行 listen 443 quic;)。

  4. 开发者要为 h2/h3 改业务代码吗? 几乎不用。要改的是部署配置(Nginx listen)与前端资源策略(去掉域名分片、重新评估合并策略)。Controller、状态码、头语义全部不变。

  5. ALPN 在整个链路里扮演什么角色? TLS 握手时客户端与服务端协商「用哪个应用协议」:客户端报 h2, http/1.1,服务端选一个。证书没问题但 ALPN 没协商到 h2,浏览器就回落 1.1——所以查协议问题时,curl -v 看 ALPN 行比看 Nginx 配置更直接。

  6. 同一页面又 h2 又 1.1 正常吗? 正常。主域走本站 h2,第三方脚本走对方 1.1;或 CDN 边缘支持 h2 而源站不支持。逐行看 Protocol,别看一条就下结论。

错法对照

错法问题正解
上了 h2 就不做缓存与压缩协议只省传输开销,数据量照旧协议 + 缓存 + 压缩三层叠加
继续「多域名分片」当优化每个域多一条 TCP 握手,破坏单连接复用同域 + h2/h3,让浏览器自己并发
把 Server Push 当新项目必选项浏览器已移除支持,实战命中率低用 <link rel=preload> 与缓存策略
TTFB 5 秒,却纠结协议是不是 h2慢在业务/DB,不在传输先看 Timing 分段与后端日志
以为 h2 改了方法/状态码语义应用语义完全没变语义照旧,照方法课/状态码课写代码

卡点急救

  1. 配了 listen 443 ssl http2 浏览器仍显示 1.1:老版本 Nginx 与 http2 指令位置有讲究,nginx -V 看编译参数是否含 http_v2_module;浏览器与服务器之间若有企业代理/SSL 检查设备会强制降级——换手机热点网络验证。
  2. 开启 h2 后个别请求变慢:h2 对同一连接上的大响应会占用带宽影响其它 stream;给静态大文件与 API 分域/分流,或开启 http2_body_preread_size 等调优。先用 Timing 确认慢在传输还是 TTFB,再动手。
  3. 想上 h3 但部分用户连不上:UDP 443 被防火墙/运营商拦是常态。保持 listen 443 quic; 与 listen 443 ssl; 并存 + Alt-Svc 头 advertise,客户端探测失败自动回落 h2——设计目标就是「有则更快,无则照常」。

面试常问

  • HTTP/2 相比 HTTP/1.1 的主要改进? ① 二进制分帧:报文拆成帧,单连接可交错多 stream;② 多路复用:解决 1.1 一连接一请求的应用层队头阻塞;③ 头压缩 HPACK:去掉重复头;④ 服务器推送(现已弃用)与流优先级。附带:浏览器侧 h2 实际要求 HTTPS。

  • HTTP/2 的队头阻塞解决了吗?HTTP/3 呢? 应用层解决了,TCP 层没有:所有 stream 共享一条 TCP,丢包时整条连接的流都等重传。HTTP/3 用 QUIC(UDP)替代 TCP,流之间独立确认恢复,单流丢包不拖其它流,另有连接迁移(换网不断线)与更快握手。

  • 为什么浏览器几乎只在 HTTPS 上提供 HTTP/2? h2 规范要求 ALPN 协商,而 ALPN 是 TLS 扩展;明文 h2c 存在但主流浏览器不实现。后果是 h2 与 HTTPS 绑定部署——这也顺带把加密变成了现代 Web 的默认。

自测三问

  1. HTTP/1.1 与 HTTP/2 各自如何实现「并行传多个资源」?瓶颈分别在哪?
  2. 如何在 Chrome 确认 /tracks 走了 h2?如何用 curl 验证并查看 ALPN 协商?
  3. 为什么说「协议升级不能替代 CDN 缓存」?各解决的是哪一层的问题?

小结一句话

HTTP/2 单连接多路复用、HTTP/3 用 QUIC 连 TCP 队头阻塞一起解决——应用语义始终是 HTTP,部署层开 h2/h3,应用层继续做好压缩、缓存与体积。

延伸

  • MDN:HTTP/2
  • MDN:HTTP 的演变
  • 下一课:应用层缓存对照——浏览器/CDN、Nginx、Redis 三层缓存各管什么,「后台改了数据前台仍旧」时按层定位。
加载本节练习…
← 上一课REST 与资源设计下一课 →应用层缓存对照