nginx 里 keepalive_timeout 设了 65,抓包看到每个请求后服务端都发 FIN,Connection 头是 close,QPS 只有 800。日志里能对上时间点,这种反而好排。

上游返回的 Connection: close 会覆盖 keep-alive 设置,连接用完就关。HTTP/1.0 的客户端默认也是短连接,不带 Connection: keep-alive 就不会复用。这一点先确认清楚,后面就不用反复试。

curl -I https://example.com
curl -s -o /dev/null -w '%{num_connects}' https://example.com

「Keep-Alive 失效」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

处理上按这个顺序:先看上游响应头里的 Connection 值;给 upstream 配 keepalive 连接池;协议统一写成 HTTP/1.1;用 num_connects 确认复用是否真的生效。

结果对不对很好判断,连续 100 次请求的 num_connects 从 100 降到 1,QPS 提到 4200。

作者 9823189