症状
本篇调试指南针对“HTTP 408 Request Timeout — 客户端发送过慢”。内容涵盖可观察的症状、可复现的诊断路径、根本原因、具体修复方式,以及如何验证修复并防止回归。
可观察到的症状包括:
- 服务器对慢速链路上的上传返回 408 Request Timeout
- 仅移动或高延迟网络下请求失败
- 日志显示 “client timed out while reading request headers”
诊断
先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。
步骤 1
curl --limit-rate 1k --max-time 60 -X POST https://api.example.com/upload --data-binary @big.bin -i
限速下出现 408,指向发送超时而非负载问题。
步骤 2
grep -rn "client_header_timeout\|send_timeout\|request_timeout" /etc/nginx/
超时低于真实客户端延迟会产生误报 408;过小并非总是安全。
常见诱因(按出现频率排序):
- 客户端发送完整请求头或请求体耗时过长
- 服务端或代理的发送超时小于真实客户端延迟
- 存在故意缓慢发送数据的 slow-loris 式连接
根因
当客户端未在配置超时内完成请求发送时,服务端以 408 关闭连接。这可防护 slow-loris 攻击,但也会惩罚真正缓慢的客户端。
修复
把客户端发送超时提高到匹配真实延迟,保持合理的 keepalive,大请求体用分块上传,并在边缘做限流,而非仅对慢客户端超时。
注意:过长超时会扩大 slow-loris 攻击窗口;应把宽松超时与连接数及请求速率限制结合。
# nginx: tune client send timeouts
client_header_timeout 30s;
client_body_timeout 30s;
send_timeout 30s;
keepalive_timeout 65s;
# rate limit abusive clients at the edge
limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s;
limit_conn_zone $binary_remote_addr zone=conn:10m;
验证
重试慢速上传并确认完成且无 408;验证故意滥用式的慢连接仍被拒绝。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。