附录:速查表、检查清单与抓包手册

这三份附录,是给你放在工位旁边、随时翻阅的”工具手册”。不是用来读的,是用来查的。


附录 A:场景 → 知识点速查表

用法:找到你遇到的”现象”,跳到对应章节和知识点。

一、文件与数据传输

现象根因知识点章节
大文件上传到一半失败没处理边界/超时Content-Length vs chunked02
下载文件浏览器直接打开缺 Content-Dispositionattachment02
做不了断点续传没支持 Range206 + Content-Range04、10
上传到一半才被拒没先问Expect: 100-continue04
传了 5MB 报 unexpected EOF长度承诺没兑现Content-Length 是承诺02

二、登录与鉴权

现象根因知识点章节
登录后一刷新就掉线session 存了服务器内存无状态 + 共享存储09
跨域带不上 CookieSameSite/作用域Domain/Path/SameSite09
JS 读不到 CookieHttpOnly 是特性防 XSS09
加机器后登录态丢失状态存本地Redis 集中存储09
用户 A 看到 B 的数据缓存污染Vary: Cookie08

三、性能

现象根因知识点章节
本地快线上慢握手成本RTT、TCP+TLS 握手07
第一个请求慢,后面快建连 + 慢启动连接复用07
加机器没用队头阻塞/下游瓶颈HOL07、12
QPS 卡在某个数连接池太小MaxIdleConnsPerHost07
too many open files连接泄漏读 body + Close07

四、实时通信

现象根因知识点章节
轮询打垮服务器无效请求太多长轮询/SSE/WebSocket14
WebSocket 连几分钟就断中间设备空闲超时心跳14
Nginx 后 WebSocket 连不上没放行 Upgrade101 升级14
并发写 panicWebSocket 不支持并发写写泵14

五、幂等与重复

现象根因知识点章节
双击下两单操作不幂等幂等性03
回调重试重复扣款服务端没幂等Idempotency-Key03
重试风暴没退避/抖动指数退避 + jitter03
GET 删除数据GET 有副作用安全方法03

六、缓存

现象根因知识点章节
发新版看不到缓存没失效强缓存/协商缓存08
什么都没配却被缓存启发式缓存(Date-Last-Modified)×10%08
用户看到别人数据缓存污染private + Vary08
CDN 不回源缓存键问题URL 版本化08

七、跨域(CORS)

现象根因知识点章节
上线就报 CORS同源策略(浏览器)不是服务端问题05
多出 OPTIONS 请求预检非简单请求05
带自定义头就报错没 Allow-HeadersAccess-Control05

八、状态码与错误

现象根因知识点章节
监控一片绿但用户炸了全返回 200状态码语义04
502/503/504 分不清网关/上游/超时精确语义04
刷新 POST 重复提交没用 303PRG 模式04
限流不知道等多久没 Retry-After429 + Retry-After04

九、安全

现象根因知识点章节
token 明文裸奔没 HTTPS认证≠加密11
base64 当加密编码≠加密Basic11
请求被重放没防重放nonce + timestamp11
中间人攻击InsecureSkipVerifyTLS 身份认证11
降级攻击没 HSTSStrict-Transport-Security11

十、演进与兼容

现象根因知识点章节
升级 h2 老客户端崩不兼容变更版本号/协商15
加字段老客户端崩没向后兼容只增不改15
中间设备拦新流量中间件僵化GREASE/换地基13、15

附录 B:协议设计检查清单(21 条)

用法:设计任何协议,按这 21 条逐项过一遍。它浓缩了全书所有原则。

一、地基(不变量)—— 这些一旦定错,改不动

  1. ☐ 边界方案明确吗?(长度前缀 / 分隔符 / 关闭连接)接收方怎么知道”报文到哪结束”?
  2. ☐ 字节序定死了吗?(大端/小端)多字节数字双方解析一致吗?
  3. ☐ 版本号位置固定吗? 接收方能”先读版本号,再决定怎么解析”吗?
  4. ☐ 有防误连的标识吗?(魔数/握手验证)能挡住”误连的、不懂协议的设备”吗?

二、语义 —— 每一层表达自己那层的语义

  1. ☐ 错误模型分类了吗? 第一位是不是”能不能重试”?
  2. ☐ 幂等与去重设计了吗? 重复请求会被重复执行吗?
  3. ☐ 超时语义清晰吗? deadline 传递了吗?还是每跳各自超时?
  4. ☐ 每个操作的语义明确吗? 有没有”语义含糊”的操作(像 POST 那样)?

三、扩展 —— 扩展点的精髓在”降级”

  1. ☐ 扩展点预留了吗?(版本/标志位/新类型/TLV)未来能加东西吗?
  2. ☐ 每个扩展点配了”优雅降级”吗? 老实现遇到新东西会崩溃吗?
  3. ☐ 不变量和扩展点区分清楚了吗? 哪些是”被依赖做决策”的地基,哪些是”被传递”的扩展点?

四、可靠 —— 弱网/异常下的表现

  1. ☐ 有序号/去重/补发机制吗? 消息会丢、会重、会乱序吗?
  2. ☐ 有重连策略吗?(心跳、退避、抖动)断线了怎么办?
  3. ☐ 有多路复用的话,做流控了吗? 某个流会饿死别的流吗?

五、安全 —— 分层安全,各管一段

  1. ☐ 认证了吗?(握手 + 凭证)知道对方是谁吗?
  2. ☐ 防篡改了吗?(签名/HMAC)内容被改能发现吗?
  3. ☐ 防重放了吗?(时间戳 + nonce)抓包重发能防住吗?
  4. ☐ 传输加密了吗? 内容会被窃听吗?

六、工程 —— 能落地 > 正确

  1. ☐ 可调试吗? 有日志、抓包工具吗?
  2. ☐ 可测试吗? 能 mock、能 fuzz 吗?
  3. ☐ 有文档吗? 协议规范 + 版本历史,新人能看懂吗?

最后,第 0 条(最重要):

☐ 你论证过”为什么不直接用现成的方案”吗? 造轮子的正当理由,要么”覆盖不到我的场景”,要么”我的差异化优势足够大”。答不上来,就先用现成的。


附录 C:抓包实战手册

用法:遇到”诡异问题”,按这个手册抓包定位。工具三个:curl(简单)、Wireshark(深入)、mitmproxy(看 HTTPS 明文)。

一、curl:最快的原始报文查看

# 看完整请求和响应(含首部)
curl -v https://example.com/api/user
 
# 只看响应头
curl -I https://example.com/api/user
 
# 看连接和 TLS 细节(握手、ALPN 协商结果)
curl -v --http2 https://example.com 2>&1 | grep -E "ALPN|HTTP/2"
 
# 手动发一个带 Range 的请求
curl -v -H "Range: bytes=0-99" https://example.com/big.iso

看什么:

  • > 开头的行是你发出的请求。
  • < 开头的行是收到的响应。
  • 重点看:状态码、Content-Length、Cache-Control、Transfer-Encoding、Location。

二、Wireshark:深入协议层

# 过滤只看 HTTP
http
 
# 只看某个域名
http.host == "example.com"
 
# 只看握手(TCP 三次握手 + TLS 握手)
tcp.flags.syn == 1 || tls.handshake
 
# 只看重传(TCP 层队头阻塞的线索)
tcp.analysis.retransmission

看什么:

  1. TCP 三次握手:看 SYN → SYN-ACK → ACK,确认握手正常。
  2. TLS 握手:看 ClientHello/ServerHello,确认 ALPN 协商结果。
  3. 重传:tcp.analysis.retransmission,重传多 = 丢包 = 弱网/队头阻塞。
  4. RST/FIN:看谁先断的连接(排查”幽灵连接”)。

三、mitmproxy:看 HTTPS 明文

HTTPS 抓包是密文,看不到内容。mitmproxy 通过”中间人”方式解密:

# 启动,监听 8080
mitmproxy -p 8080
 
# 浏览器/客户端配置代理到 localhost:8080,并信任 mitmproxy 的根证书

看什么:

  • 解密后的完整请求/响应(含首部和 body)。
  • 适合排查”代理改了我的头”、“Content-Encoding 对不对”这类问题。

注意:mitmproxy 本质是”企业 MITM 代理”(第 11 章讲过),它会解密你的流量。只在本地调试用,别用于生产数据。

四、Go 里直接抓自己的请求

// 打印请求的原始信息(不依赖外部工具)
resp, _ := http.Get("https://example.com")
fmt.Printf("状态码: %s\n", resp.Status)
fmt.Printf("Protocol: %s\n", resp.Proto)       // HTTP/1.1 还是 HTTP/2.0
for k, v := range resp.Header {
    fmt.Printf("%s: %s\n", k, v)
}
// resp.Proto 能告诉你 ALPN 协商出了什么协议

五、抓包定位问题的”黄金五问”

1. 请求发出去了吗?   → 有没有这条记录
2. 到达服务器了吗?   → 服务器 access log 有没有
3. 请求长什么样?     → 方法、URL、Host、长度、被代理改过吗
4. 响应长什么样?     → 状态码、首部、body 完整吗
5. 被重试了几次?     → 客户端/网关/服务器三边对齐

全书完。墨叔,于北京。