记录一下那天晚上的排查过程。Nginx 1.24 的 access_log 里一天出现四千条 000,$request_time 全是 0.000,浏览器访问又完全正常,换 log_format、reload 配置都没变化。

刚开始盯着「上游 PHP-FPM 队列排满导致连接被重置,日志仍记 000」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。000 是 Nginx 没拿到状态码就落盘,通常是客户端提前断开。还有一种是蜘蛛超时断开时不会等响应写完,长查询正好触发。

另外,代理层 keepalive 先于源站超时,连接被中途掐断。

第一件事是确认这些 000 落在哪些路径

awk '$9=="000"{print $7}' access.log | sort | uniq -c | sort -rn | head

再看请求耗时与上游时间

awk '$9=="000"{print $7,$NF}' access.log | head -20

接着把慢查询单独记一份日志

log_format slow '$remote_addr $request_uri $request_time $upstream_response_time';

给 PHP-FPM 池加排队上限

pm.max_children = 40
request_terminate_timeout = 30s

别只看报错消失,验证要多做一步。000 条数从每天四千降到两百以内,$upstream_response_time 不再出现横杠,同一路径的重复请求也消失。

容易忽略的是,000 不是服务器返回的状态码,别按 5xx 处理,先去客户端超时和上游排队两头找。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189