线上的 HTTP
请求行为经常和本地测试不一致——响应头被代理改写、缓存层返回了过期内容、TLS
握手失败但浏览器只显示
ERR_CONNECTION_RESET。面对这些问题,靠猜是不行的,必须有系统化的调试方法和工具链。
HTTP 调试的核心原则是”分层隔离”:把请求链路拆成 DNS 解析、TCP 连接、TLS 握手、请求发送、服务端处理、响应传输六个阶段,逐段定位瓶颈。本文围绕三个核心工具——curl、Chrome DevTools、mitmproxy——构建完整的 HTTP 调试方法论。
一、curl:命令行 HTTP 调试的瑞士军刀
curl 是最基础也是最强大的 HTTP 调试工具。它不依赖浏览器、不走系统代理、不受缓存干扰,能精确控制请求的每一个细节。
1.1 基础调试:查看完整请求响应
# -v (verbose) 显示完整的请求/响应头和 TLS 握手信息
curl -v https://api.example.com/health
# 输出示例:
# * Trying 93.184.216.34:443...
# * Connected to api.example.com (93.184.216.34) port 443
# * ALPN: offers h2,http/1.1
# * TLSv1.3 (OUT), TLS handshake, Client hello (1):
# * TLSv1.3 (IN), TLS handshake, Server hello (2):
# * TLSv1.3 (IN), TLS handshake, Certificate (11):
# * TLSv1.3 (IN), TLS handshake, CERT verify (15):
# * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
# * ALPN: server accepted h2
# > GET /health HTTP/2
# > Host: api.example.com
# > User-Agent: curl/8.4.0
# > Accept: */*
# >
# < HTTP/2 200
# < content-type: application/json
# < cache-control: no-store
# < x-request-id: abc-123
# <
# {"status":"healthy"}
# -I 只获取响应头(HEAD 请求)
curl -I https://example.com
# -s 静默模式 + -o /dev/null 丢弃 body,只看头
curl -s -o /dev/null -D - https://example.com1.2 请求定制:模拟各种客户端行为
# 指定 HTTP 方法
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name":"test","email":"test@example.com"}'
# 发送表单数据
curl -X POST https://example.com/login \
-d "username=admin&password=secret"
# 上传文件
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/document.pdf" \
-F "description=test upload"
# 指定自定义头
curl -H "Authorization: Bearer eyJ..." \
-H "X-Request-ID: debug-001" \
-H "Accept: application/json" \
https://api.example.com/users/me
# 指定 Cookie
curl -b "session=abc123; lang=zh-CN" https://example.com
# 保存和发送 Cookie(模拟浏览器的 Cookie 行为)
curl -c cookies.txt https://example.com/login -d "user=admin&pass=secret"
curl -b cookies.txt https://example.com/dashboard1.3 –trace:字节级协议分析
当 -v 的信息不够时,--trace
提供了最底层的调试能力:
# 输出完整的字节流(十六进制 + ASCII)
curl --trace trace.log https://example.com
# --trace-ascii 只看 ASCII 部分(更可读)
curl --trace-ascii - https://example.com 2>&1 | head -40
# 输出示例:
# == Info: Trying 93.184.216.34:443...
# == Info: Connected to example.com (93.184.216.34) port 443
# => Send SSL data, 512 bytes (0x200)
# 0000: 16 03 01 01 fb 01 00 01 f7 03 03 ...
# <= Recv SSL data, 155 bytes (0x9b)
# ...
# => Send header, 78 bytes (0x4e)
# 0000: GET / HTTP/2
# 0014: Host: example.com
# 0027: User-Agent: curl/8.4.0
# 003f: Accept: */*
# <= Recv header, 13 bytes (0xd)
# 0000: HTTP/2 200
# --trace-time 添加时间戳(分析延迟)
curl --trace-ascii - --trace-time https://example.com 2>&1 | head -20
# 09:15:32.456789 == Info: Trying 93.184.216.34:443...
# 09:15:32.478123 == Info: Connected ...
# 09:15:32.534567 => Send SSL data ...1.4 –resolve:绕过 DNS 的精确调试
线上排查时,经常需要把请求发到特定的后端 IP,绕过 DNS 和负载均衡:
# 将 api.example.com 强制解析到指定 IP
curl --resolve api.example.com:443:10.0.1.50 \
https://api.example.com/health
# 同时指定多个域名
curl --resolve api.example.com:443:10.0.1.50 \
--resolve cdn.example.com:443:10.0.2.100 \
https://api.example.com/page
# 配合 --connect-to 重定向连接(不改变 Host 和 SNI)
curl --connect-to api.example.com:443:backend-01.internal:443 \
https://api.example.com/health
# 实际用途:
# 1. 灰度发布时测试特定后端
# 2. CDN 回源问题排查,直连源站
# 3. DNS 切换前验证新服务器
# 4. 多数据中心环境验证特定节点1.5 timing 模板:HTTP 性能分解
curl 的 -w
参数可以输出请求的每个阶段耗时,这是 HTTP
性能分析的基础:
# 创建 timing 模板文件
cat > curl-timing.txt << 'EOF'
dns_lookup: %{time_namelookup}s\n
tcp_connect: %{time_connect}s\n
tls_handshake: %{time_appconnect}s\n
time_redirect: %{time_redirect}s\n
time_pretransfer: %{time_pretransfer}s\n
starttransfer: %{time_starttransfer}s\n
total_time: %{time_total}s\n
download_speed: %{speed_download} bytes/s\n
http_code: %{http_code}\n
remote_addr: %{remote_ip}:%{remote_port}\n
ssl_verify: %{ssl_verify_result}\n
num_redirects: %{num_redirects}\n
EOF
# 使用 timing 模板
curl -s -o /dev/null -w "@curl-timing.txt" https://example.com
# 输出示例:
# dns_lookup: 0.004123s ← DNS 解析耗时
# tcp_connect: 0.025456s ← TCP 三次握手完成
# tls_handshake: 0.078912s ← TLS 握手完成
# time_redirect: 0.000000s ← 重定向耗时
# time_pretransfer: 0.079034s ← 准备发送请求
# starttransfer: 0.156789s ← 收到第一个字节(TTFB)
# total_time: 0.234567s ← 请求总耗时
# 计算各阶段耗时:
# DNS 解析: time_namelookup = 4.1ms
# TCP 连接: time_connect - time_namelookup = 21.3ms
# TLS 握手: time_appconnect - time_connect = 53.5ms
# 服务端处理: time_starttransfer - time_appconnect = 77.9ms
# 内容传输: time_total - time_starttransfer = 77.8ms# 批量测试脚本 — 多次请求取统计值
#!/bin/bash
URL="${1:-https://example.com}"
N="${2:-10}"
echo "Testing $URL ($N requests)..."
echo "---"
for i in $(seq 1 $N); do
curl -s -o /dev/null \
-w "%{time_namelookup} %{time_connect} %{time_appconnect} %{time_starttransfer} %{time_total}" \
"$URL"
echo ""
done | awk '{
dns+=$1; tcp+=$2; tls+=$3; ttfb+=$4; total+=$5; n++
} END {
printf "Average over %d requests:\n", n
printf " DNS: %.3fms\n", (dns/n)*1000
printf " TCP: %.3fms\n", ((tcp-dns)/n)*1000
printf " TLS: %.3fms\n", ((tls-tcp)/n)*1000
printf " TTFB: %.3fms\n", ((ttfb-tls)/n)*1000
printf " Total: %.3fms\n", (total/n)*1000
}'1.6 TLS 调试
# 查看服务端证书链
curl -v --head https://example.com 2>&1 | grep -A 20 "Server certificate"
# 指定 TLS 版本
curl --tlsv1.2 --tls-max 1.2 https://example.com # 强制 TLS 1.2
curl --tlsv1.3 https://example.com # 要求 TLS 1.3
# 指定密码套件
curl --ciphers ECDHE-RSA-AES128-GCM-SHA256 https://example.com
# 使用客户端证书(mTLS)
curl --cert client.pem --key client-key.pem \
--cacert ca.pem \
https://mtls.example.com/api
# 跳过证书验证(仅调试用!)
curl -k https://self-signed.example.com
# 使用指定 CA 证书
curl --cacert /path/to/custom-ca.pem https://internal.example.com1.7 HTTP/2 与协议协商
# 强制使用 HTTP/2
curl --http2 -v https://example.com 2>&1 | grep "ALPN\|HTTP/2"
# 使用 HTTP/1.1(禁用 HTTP/2)
curl --http1.1 https://example.com
# 查看 ALPN 协商结果
curl -v https://example.com 2>&1 | grep "ALPN"
# * ALPN: offers h2,http/1.1
# * ALPN: server accepted h2
# 明文 HTTP/2(h2c,仅限本地调试)
curl --http2-prior-knowledge http://localhost:8080/api二、Chrome DevTools Network:可视化请求分析
Chrome DevTools 的 Network 面板是前端和全栈工程师最常用的 HTTP 调试工具。它提供了比 curl 更直观的可视化分析能力。
2.1 Network 面板核心功能
Network 面板的关键区域:
┌─────────────────────────────────────────────────────────────┐
│ [Filter Bar] XHR | JS | CSS | Img | Media | Font | Doc │
│ □ Preserve log □ Disable cache □ No throttling ▼ │
├─────┬──────────┬────────┬──────┬──────┬───────────────────┤
│Name │ Status │ Type │ Size │ Time │ Waterfall │
├─────┼──────────┼────────┼──────┼──────┼───────────────────┤
│api/v│ 200 │ fetch │ 1.2KB│ 234ms│ ████ │
│style│ 200 │ style │ 45KB │ 89ms │ ██ │
│app.j│ 200 │ script │ 180KB│ 456ms│ ██████████ │
│logo │ 304 │ png │ 0 │ 12ms │ █ │
└─────┴──────────┴────────┴──────┴──────┴───────────────────┘
关键选项说明:
- Preserve log: 跨页面导航保留日志(调试重定向必开)
- Disable cache: 禁用缓存(模拟首次访问)
- Throttling: 模拟慢速网络(3G/Slow 3G)
2.2 Timing 面板:请求阶段分解
单击一个请求,切换到 Timing 标签,可以看到请求的每个阶段耗时:
Request Timing 分解:
Queueing 0.12ms ← 在浏览器队列中等待
Stalled 2.34ms ← 等待可用连接(受限于同域 6 连接)
DNS Lookup 4.56ms ← DNS 解析
Initial connection 23.45ms ← TCP 连接建立
SSL 34.56ms ← TLS 握手
Request sent 0.23ms ← 请求发送
Waiting (TTFB) 145.67ms ← 等待服务端响应(最关键指标)
Content Download 12.34ms ← 响应内容下载
总时间: 223.27ms
各阶段问题诊断:
- Queueing 长: 浏览器队列拥塞,请求过多或优先级低
- Stalled 长: 连接池用尽,检查是否有同域并发限制
- DNS Lookup 长: DNS 配置问题,考虑 DNS 预取
- SSL 长: 证书链验证慢,考虑 OCSP Stapling
- TTFB 长: 服务端处理慢,需要后端优化
- Download 长: 响应体过大,考虑压缩或分页
2.3 过滤与搜索
Filter Bar 的高级过滤语法:
# 按域名过滤
domain:api.example.com
# 按状态码过滤
status-code:500
status-code:304
# 按大小过滤
larger-than:100k
larger-than:1M
# 按类型过滤
mime-type:application/json
# 按方法过滤
method:POST
# 按头字段过滤
has-response-header:set-cookie
# 按 Cookie 过滤
cookie-domain:example.com
cookie-name:session
# 多条件组合
domain:api.example.com status-code:500 method:POST
# 正则匹配
/api\/v[12]\/.*/
# 排除特定请求(减号前缀)
-domain:cdn.example.com
-status-code:200
2.4 请求阻断与改写
DevTools 可以阻断或修改请求,无需改代码:
请求阻断(Request Blocking):
1. 打开 Network 面板
2. Ctrl+Shift+P → 输入 "block" → 选 "Show Request Blocking"
3. 添加 URL 模式: *.analytics.com
效果: 所有匹配的请求返回 ERR_BLOCKED_BY_CLIENT
用途:
- 测试第三方脚本加载失败时的降级行为
- 验证 CSP 策略效果
- 排除特定资源对性能的影响
Local Overrides(本地覆盖):
1. Sources → Overrides → 选择本地文件夹
2. Network → 右键请求 → Override content
3. 修改响应内容,刷新页面生效
用途:
- 修改 API 响应测试前端边界情况
- 修改 CSS/JS 而不改服务端
- 添加/修改响应头测试安全头配置
2.5 Copy as cURL:桥接浏览器与命令行
操作: 右键请求 → Copy → Copy as cURL
复制结果包含浏览器发送的完整请求信息:
- URL、Method
- 所有 Headers(包括 Cookie、Authorization)
- Request Body(POST/PUT)
- 压缩接受头(Accept-Encoding)
curl 'https://api.example.com/users' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'cookie: session=abc123' \
-H 'user-agent: Mozilla/5.0 ...' \
--compressed
技巧:
- 在终端重放浏览器请求,验证是否是前端问题
- 修改参数重复测试
- 分享给后端同事复现问题
- 导入 Postman/Insomnia 保存为接口测试用例
2.6 Performance Insights:Waterfall 深度分析
Waterfall 列的颜色含义:
████ 绿色 — 等待响应 (TTFB)
████ 蓝色 — 内容下载
████ 橙色 — SSL/TLS 握手
████ 灰色 — 排队/阻塞
████ 白色 — DNS 查询
关键模式识别:
1. 阶梯式瀑布(Staircase)
请求串行执行,一个完成后才开始下一个
原因: 资源有依赖关系或请求链过长
优化: 减少请求链深度,使用 preload 预加载
2. 长尾请求(Long Tail)
大部分请求很快完成,少数请求耗时极长
原因: 慢 API、大文件下载、第三方资源
优化: 异步加载、设置超时、使用 CDN
3. 并发饱和(Saturated Parallel)
6 条请求并行,后续排队等待
原因: HTTP/1.1 同域 6 连接限制
优化: 升级 HTTP/2、域名拆分(权宜之计)
三、mitmproxy:可编程的中间人代理
mitmproxy 是一个交互式的 HTTPS 代理,可以拦截、查看、修改和重放 HTTP/HTTPS 流量。它比浏览器 DevTools 更灵活,比 curl 更适合持续监控。
3.1 安装与基本使用
# 安装
pip install mitmproxy
# 三种模式:
mitmproxy # 终端交互 UI
mitmweb # Web 界面(推荐初学者)
mitmdump # 命令行模式(适合脚本集成)
# 启动(默认监听 8080 端口)
mitmproxy -p 8080
# 配置系统代理或应用代理
export http_proxy=http://127.0.0.1:8080
export https_proxy=http://127.0.0.1:8080
# curl 通过 mitmproxy
curl -x http://127.0.0.1:8080 https://api.example.com/health
# 安装 CA 证书(HTTPS 拦截需要)
# 启动 mitmproxy 后访问 http://mitm.it 下载对应平台的证书3.2 交互式操作
mitmproxy 终端界面操作:
快捷键:
j/k 上下移动选择请求
Enter 查看请求详情
q 返回/退出
Tab 在 Request/Response/Detail 间切换
e 编辑请求/响应
r 重放请求
z 清空列表
f 设置过滤器
/ 搜索
: 命令模式
过滤表达式:
~d example.com 按域名过滤
~m POST 按方法过滤
~c 500 按响应码过滤
~t application/json 按 Content-Type 过滤
~b "error" 按 body 内容过滤
~h "Authorization" 按头字段过滤
~u /api/ 按 URL 路径过滤
~s 只显示响应
~q 只显示请求
! ~d cdn.example.com 排除特定域名
3.3 mitmdump 脚本:自动化流量分析
mitmproxy 的脚本接口允许用 Python 编写自定义的流量处理逻辑:
# slow_api_detector.py — 检测慢 API 响应
import mitmproxy.http
import time
class SlowAPIDetector:
def __init__(self):
self.threshold_ms = 500 # 超过 500ms 视为慢请求
def request(self, flow: mitmproxy.http.HTTPFlow):
flow.metadata["start_time"] = time.time()
def response(self, flow: mitmproxy.http.HTTPFlow):
start = flow.metadata.get("start_time", 0)
duration_ms = (time.time() - start) * 1000
if duration_ms > self.threshold_ms:
print(f"[SLOW] {duration_ms:.0f}ms "
f"{flow.request.method} {flow.request.pretty_url} "
f"→ {flow.response.status_code}")
addons = [SlowAPIDetector()]# response_modifier.py — 修改响应内容(模拟故障)
import mitmproxy.http
import json
class ResponseModifier:
def response(self, flow: mitmproxy.http.HTTPFlow):
# 注入延迟头以帮助调试
flow.response.headers["X-Debug-Via"] = "mitmproxy"
# 模拟 API 降级:将特定 API 的响应改为错误
if "/api/payment" in flow.request.pretty_url:
flow.response.status_code = 503
flow.response.text = json.dumps({
"error": "Service temporarily unavailable",
"retry_after": 30
})
# 移除安全头进行测试
if flow.request.pretty_url.endswith("/test-no-csp"):
flow.response.headers.pop("Content-Security-Policy", None)
addons = [ResponseModifier()]# 运行脚本
mitmdump -s slow_api_detector.py
mitmdump -s response_modifier.py
# 同时使用多个脚本
mitmdump -s slow_api_detector.py -s response_modifier.py3.4 流量录制与重放
# 录制流量到文件
mitmdump -w traffic.flow
# 回放录制的流量
mitmdump -c traffic.flow
# 服务端回放(将录制的响应作为 mock 返回)
mitmdump --server-replay traffic.flow \
--server-replay-nopop \
--server-replay-kill-extra
# 用途:
# 1. 录制生产环境流量 → 本地回放调试
# 2. 接口测试:录制正常响应 → 作为 mock server
# 3. 对比分析:录制修改前后的流量差异3.5 移动端 HTTP 调试
移动端调试步骤:
1. 确保手机和电脑在同一网络
2. 启动 mitmproxy:
mitmweb --listen-host 0.0.0.0 -p 8080
3. 手机 WiFi 设置代理: 电脑IP:8080
4. 手机浏览器访问 http://mitm.it 安装 CA 证书
iOS: 设置 → 通用 → 关于 → 证书信任设置 → 启用
Android: 设置 → 安全 → 安装证书
5. 手机上的所有 HTTP/HTTPS 流量都会经过 mitmproxy
常见问题:
证书固定(Certificate Pinning)的 App 会拒绝 mitmproxy 的证书
解决方案:
- Android: 使用 Frida 动态 hook SSL 验证
- iOS: 使用 SSL Kill Switch 2(需越狱)
- 大多数调试场景可使用应用自带的 debug 构建
四、HTTP 性能分析方法论
HTTP 性能问题的根因可能在网络、服务端或客户端。系统化的分析方法是找到瓶颈的关键。
4.1 TTFB 分解
TTFB(Time To First Byte,首字节时间)是 HTTP 性能的核心指标,它是用户感知延迟的最大组成部分。
TTFB 的组成:
TTFB = DNS + TCP + TLS + Server Processing
┌──────────┬─────────────┬──────────────┬─────────────────────┐
│ DNS 解析 │ TCP 三次握手 │ TLS 握手 │ 服务端处理 │
│ 2-50ms │ 1-100ms │ 10-200ms │ 10ms-数秒 │
└──────────┴─────────────┴──────────────┴─────────────────────┘
├─────────────── TTFB ─────────────────────────────────────────┤
各阶段优化方向:
DNS: 使用快速 DNS、DNS 预取、减少 CNAME 链
TCP: 启用 TFO、减少 RTT(使用 CDN)
TLS: TLS 1.3、Session Resumption、OCSP Stapling
Server: 应用层优化、缓存、数据库优化
# 使用 curl 测量 TTFB
curl -s -o /dev/null -w "TTFB: %{time_starttransfer}s\n" https://example.com
# 多次测量取中位数
for i in $(seq 1 20); do
curl -s -o /dev/null \
-w "%{time_starttransfer}\n" \
https://example.com
done | sort -n | awk 'NR==10{printf "P50 TTFB: %.3fms\n", $1*1000}'
4.2 HTTP 延迟分类与诊断
延迟类型 │ 表现 │ 诊断方法
──────────────────┼─────────────────────────┼──────────────────────────
网络延迟 │ TCP RTT 高 │ ping/mtr, curl timing
DNS 延迟 │ 首次访问慢,后续正常 │ dig, time_namelookup
TLS 延迟 │ HTTPS 比 HTTP 慢很多 │ curl --tlsv1.3, openssl s_time
服务端延迟 │ TTFB 高,网络 RTT 正常 │ 服务端 APM, access log
传输延迟 │ 下载时间长 │ Content-Length, 压缩检查
队头阻塞 │ 请求排队,Stalled 时间长 │ DevTools Waterfall
重定向延迟 │ 多次 3xx 跳转 │ curl -L -w redirects
4.3 端到端请求链路追踪
在微服务架构中,一个 HTTP 请求可能经过多层代理和多个服务。追踪完整链路需要利用请求 ID:
# 步骤 1: 发送带追踪 ID 的请求
REQUEST_ID="debug-$(date +%s)-$(( RANDOM % 1000 ))"
curl -v \
-H "X-Request-ID: $REQUEST_ID" \
-H "X-Debug: true" \
https://api.example.com/orders/123
# 步骤 2: 在各层日志中搜索该 ID
# Nginx access log
grep "$REQUEST_ID" /var/log/nginx/access.log
# 应用日志
grep "$REQUEST_ID" /var/log/app/application.log
# 上游服务日志
grep "$REQUEST_ID" /var/log/upstream/service.log
# 步骤 3: 对比各层的时间戳,找到延迟瓶颈
# Nginx: 10:00:00.100 → 10:00:00.500 (400ms, 代理处理)
# App: 10:00:00.110 → 10:00:00.480 (370ms, 应用处理)
# Database: 10:00:00.120 → 10:00:00.450 (330ms, 数据库查询!)
#
# 结论: 延迟主要来自数据库查询# 检查各层添加的响应头
curl -s -D - -o /dev/null https://api.example.com/orders/123 | \
grep -iE "^(x-|via|server|age|cf-)"
# 常见的调试响应头:
# X-Request-ID: abc123 ← 请求追踪 ID
# X-Response-Time: 0.234 ← 服务端处理时间
# Via: 1.1 proxy1, 1.1 proxy2 ← 经过的代理链
# X-Cache: HIT from cdn-edge-01 ← CDN 缓存命中
# Age: 3600 ← 缓存已存在时间
# Server: nginx/1.24.0 ← 服务端软件
# CF-Ray: 8a1234567890abcd-SJC ← Cloudflare 请求 ID五、专题调试场景
5.1 HTTPS 证书问题排查
# 查看证书链完整信息
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | \
openssl x509 -noout -text | \
grep -A 2 "Issuer:\|Subject:\|Not After\|DNS:"
# 检查证书过期时间
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -dates
# notBefore=Jan 1 00:00:00 2025 GMT
# notAfter=Mar 31 23:59:59 2025 GMT
# 验证证书链完整性
openssl s_client -connect example.com:443 \
-CAfile /etc/ssl/certs/ca-certificates.crt 2>&1 | \
grep "Verify return code"
# Verify return code: 0 (ok)
# 常见错误码:
# 10 — 证书过期
# 18 — 自签名证书
# 19 — CA 未知(证书链不完整)
# 20 — 无法找到本地颁发者证书
# 21 — 证书链过长
# 测试特定协议和密码套件
openssl s_client -connect example.com:443 \
-tls1_2 -cipher ECDHE-RSA-AES128-GCM-SHA2565.2 重定向链分析
# 跟踪完整的重定向链
curl -v -L https://example.com 2>&1 | grep -E "< HTTP|< location"
# 使用 -w 获取重定向统计
curl -s -o /dev/null -L -w \
"Redirects: %{num_redirects}\nFinal URL: %{url_effective}\nTotal: %{time_total}s\n" \
http://example.com
# 最大重定向次数(防止无限循环)
curl -L --max-redirs 5 http://example.com
# 常见重定向问题:
# 1. HTTP → HTTPS 重定向未设置 HSTS
# 2. www → non-www 重定向循环
# 3. Trailing slash 重定向浪费一次 RTT
# 4. 过长的重定向链(>3 次)增加延迟5.3 缓存行为验证
# 验证缓存头
curl -s -D - -o /dev/null https://example.com/style.css | \
grep -iE "^(cache-control|etag|last-modified|age|expires|vary):"
# 条件请求验证
ETAG=$(curl -sI https://example.com/style.css | grep -i etag | tr -d '\r')
curl -v -H "If-None-Match: ${ETAG#*: }" https://example.com/style.css
# 期望: HTTP 304 Not Modified
# Last-Modified 条件请求
LM=$(curl -sI https://example.com/style.css | grep -i "last-modified" | cut -d: -f2-)
curl -v -H "If-Modified-Since:$LM" https://example.com/style.css
# 期望: HTTP 304 Not Modified
# 验证 CDN 缓存命中
for i in 1 2 3; do
echo "--- Request $i ---"
curl -sI https://cdn.example.com/image.jpg | \
grep -iE "^(x-cache|age|cf-cache-status):"
sleep 1
done
# 第 1 次: X-Cache: MISS, Age: 0
# 第 2 次: X-Cache: HIT, Age: 1
# 第 3 次: X-Cache: HIT, Age: 25.4 HTTP/2 调试
# 验证 HTTP/2 支持
curl -v --http2 https://example.com 2>&1 | grep "HTTP/2"
# 使用 nghttp 查看帧级别信息
nghttp -v https://example.com 2>&1 | head -30
# [ 0.023] Connected
# [ 0.045] recv SETTINGS frame
# [ 0.045] recv WINDOW_UPDATE frame
# [ 0.045] send HEADERS frame
# [ 0.067] recv HEADERS frame
# [ 0.067] recv DATA frame
# 查看 HTTP/2 连接信息
curl -v --http2 https://example.com 2>&1 | \
grep -E "ALPN|HTTP/2|stream"
# 检测服务端是否支持 Server Push(已基本废弃)
nghttp -v https://example.com 2>&1 | grep "PUSH_PROMISE"六、调试工具对比与选型
工具 │ 最佳场景 │ 优势 │ 局限
──────────────┼───────────────────────┼──────────────────────────┼──────────────
curl │ 快速单请求测试 │ 无依赖、精确控制、脚本化 │ 无法拦截浏览器流量
│ 服务端接口调试 │ TLS/协议级诊断 │ 无可视化
│ CI/CD 自动化测试 │ │
──────────────┼───────────────────────┼──────────────────────────┼──────────────
DevTools │ 前端/全栈开发调试 │ 可视化、Waterfall 分析 │ 仅限浏览器流量
│ 页面加载性能分析 │ 与浏览器深度集成 │ 无法拦截改写
│ 快速复现前端问题 │ Copy as cURL 联动 │
──────────────┼───────────────────────┼──────────────────────────┼──────────────
mitmproxy │ HTTPS 拦截与改写 │ 可编程、支持脚本扩展 │ 需要安装 CA 证书
│ 移动端 App 调试 │ 流量录制/重放 │ Certificate Pinning
│ 故障注入/模拟降级 │ 支持 HTTP/2 │ 配置较复杂
──────────────┼───────────────────────┼──────────────────────────┼──────────────
Wireshark │ 协议级深度分析 │ 逐包分析、支持所有协议 │ 无法解密 HTTPS
│ TCP/TLS 层面排查 │ 专家信息与流图 │ 学习曲线陡
│ 抓包离线分析 │ 强大的过滤表达式 │ 不适合日常调试
──────────────┼───────────────────────┼──────────────────────────┼──────────────
httpie │ API 开发测试 │ 语法友好、JSON 高亮 │ 功能不如 curl 全面
│ REST 接口快速测试 │ 默认行为更合理 │ 安装需要 Python
调试决策流程:
浏览器中的页面加载问题?
→ Chrome DevTools
服务端 API 接口问题?
→ curl(快速测试)
→ curl + timing 模板(性能分析)
需要拦截/修改 HTTPS 流量?
→ mitmproxy
移动 App 的网络问题?
→ mitmproxy(代理模式)
TCP/TLS 层面的连接问题?
→ Wireshark + tcpdump
自动化测试/监控?
→ curl + 脚本
→ mitmdump + Python 脚本
七、总结
HTTP 调试的核心是”分层隔离”——把问题定位到 DNS、TCP、TLS、应用层中的某一层,再用针对性的工具深入分析。
curl 是最基础的工具。掌握
-v、--trace、--resolve、-w四个参数就能解决大部分调试需求。timing 模板是分析 HTTP 性能的利器。DevTools 提供直观的可视化分析。Waterfall 图可以快速定位并发瓶颈和串行瓶颈。“Copy as cURL”是连接浏览器和命令行的桥梁。
mitmproxy 是 HTTPS 调试的最强工具。可编程的脚本接口让它能胜任流量分析、故障注入、自动化测试等复杂场景。
TTFB 是 HTTP 性能的核心指标。将 TTFB 分解为 DNS + TCP + TLS + Server Processing,就能精确定位性能瓶颈。
请求 ID 是微服务环境中追踪问题的命脉。从入口到最后一个后端服务,保持同一个 X-Request-ID,就能在分布式日志中还原完整链路。
工具选型要匹配场景。日常开发用 DevTools,服务端接口用 curl,HTTPS 拦截用 mitmproxy,协议层分析用 Wireshark。不存在一个工具解决所有问题。
参考文献
- curl: How To Use (curl.se/docs/manpage.html)
- Chrome DevTools: Network Reference (developer.chrome.com)
- mitmproxy Documentation (docs.mitmproxy.org)
- RFC 9110: HTTP Semantics — 状态码与方法定义
- Web Performance: HTTP/2 in Action (Manning)
上一篇:HTTP 安全头完整实战:CORS、CSP、HSTS
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【网络工程】零拷贝网络:sendfile、splice 与 MSG_ZEROCOPY
数据从磁盘到网卡的传统路径涉及 4 次拷贝和多次上下文切换。本文系统剖析 sendfile、splice、vmsplice、MSG_ZEROCOPY 四种零拷贝技术的内核实现、适用场景与性能差异,并以 Kafka 和 Nginx 为案例分析零拷贝在生产系统中的工程实践。
【网络工程】CDN 故障调试:缓存命中率、回源异常与头分析
CDN 故障排查是运维工程中的高频场景。本文系统覆盖缓存未命中分析、回源异常诊断、CDN 响应头解读、性能监控体系搭建四个维度,提供从现象到根因的排查方法论。
【网络工程】代理性能调优:缓冲、Keepalive 与连接复用
系统剖析反向代理层的性能瓶颈与调优方法——Proxy Buffer 内存控制、上下游 Keepalive 参数协调、HTTP/2 连接复用行为、代理层 CPU/内存/连接数监控与容量规划。
【网络工程】TCP 调优实战:内核参数与 socket 选项完全指南
TCP 内核参数和 socket 选项是网络性能的最后一道关卡。本文系统梳理 Linux TCP 参数体系,从缓冲区、Backlog 队列、Keepalive、TIME_WAIT 到拥塞控制,给出不同场景的调优模板和基准测试方法论。