28. 网络应用层协议深入

系统掌握应用层协议核心:HTTP 报文与语义演进(1.0/1.1/2/3)、HTTP 缓存与条件请求、Cookie/Session 与鉴权、DNS 解析流程与记录类型、TLS 握手与证书链、WebSocket 与长连接、以及 CDN 与 QUIC 的工程架构实践。

1. HTTP 的报文与语义

1.1 请求/响应结构

HTTP 是无状态文本协议:请求行 + 头 + 体。理解报文结构是排查一切 Web 问题的地基。

# 请求
# GET /api/users HTTP/1.1
# Host: example.com
# Authorization: Bearer xxx
# Accept: application/json
# 响应
# HTTP/1.1 200 OK
# Content-Type: application/json
# Content-Length: 42

1.2 方法与幂等性

# GET: 幂等、可缓存(安全)
# POST: 非幂等、不可缓存(提交/创建)
# PUT: 幂等(整体替换)
# PATCH: 非幂等(部分修改)
# DELETE: 幂等
# HEAD/OPTIONS: 查元信息

工程意义:REST API 设计要尊重语义——GET 不该改状态、PUT 可安全重试、POST 才是有副作用的入口。语义错了,缓存与重试机制都会踩坑。

2. HTTP 版本演进

2.1 1.0 / 1.1 / 2 / 3 的差异

版本核心改进关键机制
1.0每个请求一个连接短连接
1.1长连接 + 管线化keep-alive、Host 头、chunked
2.0多路复用 + 二进制帧单连接并发请求、头部压缩 HPACK
3.0基于 UDP 的 QUIC0-RTT、无队头阻塞、连接迁移

队头阻塞是演进主线:1.1 的 TCP 队头阻塞 → 2.0 用多路复用缓解应用层、但 TCP 层仍阻塞 → 3.0 用 QUIC(UDP 上自建可靠传输)彻底解决传输层队头阻塞。

2.2 何时上 HTTP/3

HTTP/3 适合弱网、移动网络、首屏性能敏感场景(0-RTT 握手、连接迁移对网络切换友好)。但 QUIC 生态(代理、负载均衡、UDP 放行)需额外运维。内网/稳网仍用 HTTP/2,无明显收益。

3. HTTP 缓存与条件请求

3.1 缓存的两层

# 强缓存: 期限内直接用本地副本(不请求服务器)
#   Cache-Control: max-age=3600
# 协商缓存: 过期后带验证条件请求,服务器判定是否 304
#   ETag(实体标签)/ Last-Modified
#   请求带 If-None-Match / If-Modified-Since

3.2 缓存控制的关键头

  • Cache-Control:no-store(不缓存,敏感数据)、no-cache(可缓存但要验证)、public/private、max-age/s-maxage。
  • ETag:内容指纹,变化即换 ETag,比 Last-Modified 精确。
  • 浏览器 vs 代理缓存:private 只存浏览器,public 可被 CDN/代理缓存。

工程要点:静态资源用「内容哈希 + 长 max-age」(文件名含 hash,变了就换 URL),动态接口默认 no-store。缓存策略错了,要么慢要么脏。

4. Cookie、Session 与鉴权

4.1 状态管理

HTTP 无状态,靠 Cookie/Session/Token 补状态:

# Cookie: 浏览器存储,随请求自动带(受限大小,可被篡改,注意 HttpOnly/Secure/SameSite)
# Session: 服务端存状态,Cookie 存 sessionId —— 集群需共享 session(Redis)
# Token(JWT): 无状态,签名自包含,客户端保存 —— 服务端无需存 session
# 现代趋势: JWT/Token 为主(分布式友好),敏感数据仍走服务端校验

4.2 安全头与 CSRF

  • HttpOnly:JS 读不到 Cookie,防 XSS 窃取。
  • SameSite:限制跨站携带,防 CSRF(Lax 默认、Strict 更严)。
  • CSRF 防护:Token/同源校验/自定义头——POST 敏感操作必须有防跨站伪造手段。

5. DNS 解析与记录

5.1 解析流程

# 浏览器 → 本地缓存 → hosts → 本地 DNS 服务器
# → 根服务器 → TLD 服务器 → 权威服务器 → 返回 IP
# 关键: 各级缓存(TTL 决定缓存时长)
# 记录类型: A/AAAA(IP)、CNAME(别名)、MX(邮件)、NS(域名服务器)、TXT(SPF/验证)

5.2 工程常见问题

  • TTL 与变更延迟:改 DNS 要等旧 TTL 过期,变更前先调低 TTL。
  • CNAME 链过长:解析慢;避免多层 CNAME。
  • 解析劫持/污染:公共 DNS + DoH(DNS over HTTPS)缓解。
  • 故障排查:dig/nslookup 从根逐层查,先确认「解析到哪一层断了」。

6. TLS 握手与证书链

6.1 握手过程

# TLS 1.2 握手(简化)
# 1) ClientHello: 支持的加密套件 + 随机数
# 2) ServerHello + 证书: 服务器选套件 + 发证书链
# 3) 客户端验证证书(可信 CA → 链到根)
# 4) 双方交换密钥材料 → 生成会话密钥
# 5) 开始加密通信
# TLS 1.3: 更短握手(1-RTT),省略部分协商,前向安全更佳

6.2 证书与常见问题

  • 证书链:服务器发「叶证书 + 中间证书」,客户端链到根 CA 验证。中间证书缺失是最常见的「证书无效」原因。
  • 有效期:证书有有效期,过期即报错——务必监控续期(Let’s Encrypt 自动续期)。
  • SNI:多域名共用 IP,靠 SNI 选证书。

7. WebSocket 与长连接

7.1 从轮询到推送

# 轮询: 客户端定时拉(浪费)
# 长轮询: 服务器挂起直到有数据(延迟+占连接)
# SSE: 单向服务器推送(简单、自动重连、EventSource)
# WebSocket: 全双工双向(低延迟、常需自定义心跳)
# 选型: 单向推送 → SSE;双向实时(聊天/游戏/协作)→ WebSocket

7.2 WebSocket 的工程注意

  • 心跳:应用层 ping/pong 保活,防中间设备掐断空闲连接。
  • 网关/负载均衡:WS 长连接需要网关支持升级与粘性。
  • 扩展:多节点横向扩展时,消息要经中间件(Redis Pub/Sub、Kafka)跨节点路由。

8. CDN 与 QUIC 的工程实践

8.1 CDN 原理

# CDN: 内容分发 + 就近缓存
# 用户 DNS 解析到最近的边缘节点(Anycast/GSLB)
# 边缘缓存静态资源(图片/JS/CSS)→ 回源拉取未命中
# 收益: 首屏加速 + 源站减压 + 抗大流量

8.2 实践要点

  • 缓存策略配合:CDN 缓存时长与源站 Cache-Control 对齐,避免「改了源站 CDN 还是旧的」。
  • 回源保护:源站只信任 CDN 回源 IP + 限流,防刷源站。
  • QUIC 落地:CDN 边缘开 QUIC 对弱网收益明显;监控 UDP 丢包与可用性再推广。

9. 常见陷阱

  • 忘记设置 Cache-Control 导致敏感数据被缓存:登录接口、个人数据一律 no-store。
  • Cookie 未设 HttpOnly/Secure:XSS 可窃取,传输用 HTTPS 时 Cookie 需 Secure。
  • DNS TTL 改完等生效:没等旧缓存过期就判定「没生效」。
  • WebSocket 无心跳:空闲连接被中间网络掐断,重连风暴。
  • TLS 中间证书缺失:上线前用在线工具验证书链完整性。

参考文章

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「计算机基础」更多文章

  1. 27. 面向对象基础
  2. 26. 栈、队列与堆
  3. 25. IO 模型与多路复用