Appearance
网络协议与缓存
HTTP 缓存 · TCP 握手挥手 · HTTP/2/3 · HTTPS · Cookie/Session/Token/JWT/SSO · CDN · DNS
一、HTTP 缓存
1. 强缓存
Expires(HTTP 1.0):绝对时间,受本地时间影响Cache-Control(HTTP 1.1):max-age相对时间,优先级高于 Expiresno-cache:需协商缓存;no-store:禁止缓存
2. 协商缓存
Last-Modified/If-Modified-Since:基于最后修改时间(精确到秒)ETag/If-None-Match:基于文件内容编码,更精确,优先于 Last-Modified- 命中返回 304,使用本地缓存
二、TCP / HTTP 协议
1. TCP 三次握手与四次挥手
三次握手:
- 客户端 → SYN=1, seq=x → 服务端(SYN-SENT)
- 服务端 → SYN=1, ACK=1, seq=y, ack=x+1 → 客户端(SYN-RCVD)
- 客户端 → ACK=1, seq=x+1, ack=y+1 → 服务端(ESTABLISHED)
为什么三次:防止已失效的连接请求到达服务端导致错误建立连接
四次挥手:
- 主动方 → FIN=1 → 被动方(FIN-WAIT-1)
- 被动方 → ACK=1 → 主动方(CLOSE-WAIT,此时单向关闭)
- 被动方 → FIN=1 → 主动方(LAST-ACK)
- 主动方 → ACK=1 → 被动方(TIME-WAIT,等 2MSL 后 CLOSED)
为什么 TIME-WAIT:确保对方收到确认应答,若应答丢失对方会重发
2. 五层因特网协议栈
- 应用层(DNS、HTTP):DNS 解析域名,发送 HTTP 请求
- 传输层(TCP、UDP):三次握手建立 TCP 连接
- 网络层(IP、ARP):IP 寻址,路由选择
- 数据链路层(PPP):封装成帧,添加 MAC 地址
- 物理层:通过双绞线/光纤/电磁波传输比特流
3. HTTP 与 HTTPS 区别
- HTTPS = HTTP + SSL/TLS 加密,更安全
- 默认端口:HTTP 80,HTTPS 443
- HTTPS 需要 SSL 证书,性能不如 HTTP(加解密+握手开销)
4. HTTP/2 特性
| 特性 | 说明 |
|---|---|
| 多路复用 | 单 TCP 连接并行加载多资源,无并发数限制 |
| Server Push | 服务器主动推送客户端可能需要的资源 |
| 头部压缩(HPACK) | 维护头部表,后续请求只发差异字段 |
| 二进制帧传输 | HTTP 报文拆分为头部帧和数据帧,解析更高效 |
| 持久连接 | 连接永久,不依赖 keep-alive 超时 |
升级要求:Nginx ≥ 1.10.0,OpenSSL ≥ 1.0.2,基本只支持 HTTPS
HTTP/2 缺点:
- TCP 队头阻塞未彻底解决(丢包阻塞所有流)
- 丢包重传影响比 HTTP/1.1 更大
- 服务器瞬时压力暴增(无并发限制)
5. HTTPS 握手过程(TLS 1.2)
- Client-hello:客户端发送加密套件列表、随机数 random1
- Server-hello:服务端选定套件、返回证书 + 随机数 random2
- 验证证书:从根证书开始逐级验证证书链(CA 签名)
- 密钥交换:客户端生成 pre-master,用公钥加密发送;双方计算出对称会话密钥
- Finished:互发 Finished 验证握手成功,后续对称加密传输
对称加密 vs 非对称加密:握手用非对称加密协商密钥,传输用对称加密(兼顾安全与性能)
6. HTTP/3(基于 QUIC)
核心改进:基于 UDP 的 QUIC 协议,彻底解决 TCP 队头阻塞
| 特性 | 说明 |
|---|---|
| 无队头阻塞 | 每个流独立传输,丢包只影响单个流 |
| 连接迁移 | 基于连接 ID,网络切换无需重建连接 |
| 快速握手 | 0-RTT/1-RTT 建立连接(HTTP/2 需 3-RTT) |
| 内置加密 | 头部和载荷均加密 |
HTTP 协议演进:
| 版本 | 传输层 | 核心特性 | 主要问题 |
|---|---|---|---|
| HTTP/1.1 | TCP | 文本协议、持久连接 | 队头阻塞、头部冗余 |
| HTTP/2 | TCP | 多路复用、二进制帧 | TCP 队头阻塞 |
| HTTP/3 | UDP(QUIC) | 独立流、连接迁移、0-RTT | 生态尚在完善 |
7. POST 请求 Content-Type
| Content-Type | 用途 | 特点 |
|---|---|---|
application/x-www-form-urlencoded | 最常见表单 | 数据编码为 key1=val1&key2=val2 |
multipart/form-data | 文件上传 | boundary 分隔各字段,可传文件+键值对 |
application/json | JSON 格式 | 序列化 JSON 字符串 |
application/octet-stream | 二进制流 | 只传二进制数据 |
三、Cookie / Session / Token / JWT / SSO
1. Cookie
- HTTP 是无状态协议,Cookie 用于维护会话状态
- 存储在客户端,下次请求同一服务器时自动携带
- Cookie 不可跨域(同一级/二级域名间可通过 domain 共享)
| 属性 | 说明 |
|---|---|
domain | 所属域名,默认当前域名 |
path | 生效路径,默认 / |
maxAge | 失效时间(秒),负数=临时,0=删除 |
secure | 仅 HTTPS 传输 |
httpOnly | JS 无法读取(防 XSS) |
- 单个 Cookie ≤ 4KB,一个网站最多约 20 个
2. Session
- 存储在服务端,sessionId 存储在客户端 Cookie 中
- 集群部署的 Session 共享问题:多台服务器间需共享 Session(可用 Redis)
- 关闭浏览器 Session 不会立即消失:只是会话 Cookie 丢失导致找不到 Session
分布式 Session 共享方案:
| 方案 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| Session 复制 | 节点 Session 变化时广播给所有节点 | 可容错 | 网络压力大 |
| 粘性 Session | Nginx ip_hash 定向到同一服务器 | 简单 | 服务器故障则 Session 失效 |
| Session 共享(常用) | Redis/Memcached 集群缓存 | 可扩展,重启不丢失 | 架构复杂 |
| Session 持久化 | 存储到数据库 | 故障不丢失 | 数据库压力大 |
3. Cookie vs Session
| 对比项 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端 | 服务端 |
| 安全性 | 较低(可被篡改) | 较高 |
| 数据类型 | 仅字符串 | 任意类型 |
| 存储大小 | ≤ 4KB | 远大于 Cookie |
| 服务器压力 | 无 | 用户多时占用内存 |
4. Token
- 访问资源接口(API)时所需的资源凭证
- 简单组成:
uid(用户唯一标识)+time(时间戳)+sign(签名/哈希) - token 放在 HTTP Header 的
Authorization字段中 - 服务端无状态:不存储 token,用解析计算时间换取存储空间
- 可避开同源策略,可避免 CSRF 攻击
Access Token vs Refresh Token:
- Access Token 有效期短(几分钟),用于访问资源
- Refresh Token 有效期长,专用于刷新过期的 Access Token
- 流程:登录 → access+refresh token → access 过期 → 用 refresh 换新 access → refresh 也过期 → 重新登录
5. JWT(JSON Web Token)
JWT 结构(三段式,. 分隔):
Header.Payload.Signature
// 例:eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJhIn0.2jf3kl_uKWRkwjOP6uQRJFqMw- Header:算法类型(
alg: HS256)+ 令牌类型(typ: JWT),base64url 编码 - Payload:实际数据(用户信息、
iat签发时间、exp过期时间),base64url 编码 - Signature:
HMACSHA256(base64(Header) + "." + base64(Payload), secret),防篡改
防篡改原理:用户可修改 base64 数据,但无法伪造签名(因不知道 secret)
优势:无状态(可扩展)、自包含(减少数据库查询)、跨域友好(不依赖 Cookie)
缺点:无法主动废弃;默认不加密;应设置较短有效期,通过 HTTPS 传输
6. 单点登录(SSO)
同主域名:将 Cookie 的 domain 设为主域名,所有子域共享登录状态
跨主域名(真正 SSO):
- 用户访问系统 A → 未登录 → 跳转 SSO
- SSO 验证账号密码 → 种 SSO 域下凭证 + 下发
code(一次性) - 重定向回系统 A 的 callback,携带
code - 系统 A 用
code向 SSO 换取ticket,在 A 域下 set cookie - 用户访问系统 B → 未登录 → 跳转 SSO → 已有凭证 → 下发 code → B 用 code 换 ticket
关键点:code 是一次性的,暴露在 URL 中仅用于换取 ticket,换完即失效
7. Session vs Token 对比
| 对比维度 | Session | Token |
|---|---|---|
| 客户端存储 | Cookie(自动携带) | 灵活(Cookie/localStorage/Header) |
| 服务端存储 | 存储完整会话数据 | 不存储,仅校验签名 |
| CSRF 风险 | 有(Cookie 自动携带) | 无(手动放入 Header) |
| 跨端支持 | 仅浏览器(依赖 Cookie) | 全平台(APP/小程序/IoT) |
| 分布式 | 需共享存储(Redis) | 天然支持(无状态) |
四、CDN 与 DNS
1. CDN(内容分发网络)
- 原理:在用户附近部署缓存节点,就近响应用户请求
- 优势:解决跨运营商/跨地域访问问题,降低延迟;分流减轻源站负载
- 缓存策略:通过
Cache-Control: max-age控制节点缓存时间,过期则回源拉取
2. DNS 解析过程
- 浏览器自身 DNS 缓存
- 操作系统 hosts 文件
- 本地 DNS 服务器(ISP)
- 根服务器递归查询