一张图读懂Nginx常规报错,让处理报错信手拈来
上周帮一个同事排查问题,他说上传一个8M的图片报413,问我是不是Nginx出bug了。
我一看,client_max_body_size默认是1M,改到100M就好了。但他说改完了还是不行——原来后端的PHP也没配,upload_max_filesize还是2M。
一个413,折腾了他一下午。
这件事让我想把Nginx常见的报错整理一下。502、504、499、403、413、400,每个报错代表什么问题?怎么一步步排查?今天一张图讲清楚。下次你再遇到,10分钟内就能定位到问题层。
先上干货。把最常见的几个报错按“问题出在哪一层”分了类:
收到Nginx报错 → 是4xx还是5xx?
4xx(客户端问题)→ 检查客户端请求格式、权限
5xx(服务端问题)→ 检查后端服务状态、超时配置
下面我把每个报错拆开讲,结合我遇到过的案例。
这是我遇到最频繁的报错。
第一次遇到502,我以为是Nginx的问题,重启了好几次Nginx,没用。后来才发现,是后端的PHP-FPM进程挂了。
502的本质: Nginx作为网关,向后端(PHP-FPM、Tomcat、Node.js)发请求,但没收到有效响应。
常见原因和排查方法:
telnet 后端IP 端口
我当时怎么排查的:
遇到502,先做三件事:
后端服务在不在?
ps aux | grep -E "php|java|node"端口通不通?
curl -v http://127.0.0.1:8080Nginx error.log说了什么?
tail -f /var/log/nginx/error.log
这三步走完,90%的502都能定位。
配置层面的预防:
location / {
proxy_pass http://backend_servers;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_next_upstream_tries 2;
}
这样配之后,一个后端挂了,Nginx会自动尝试下一个。
504和502经常被搞混。
504的本质: Nginx向后端发了请求,在 proxy_read_timeout 规定的时间内没收到完整响应,主动断开了。
常见场景:
client_body_timeoutmax_execution_time
我当时怎么排查的:
有一次导出报表,点完按钮转了30秒,然后504了。Nginx error.log显示:
upstream timed out (110: Connection timed out) while reading response header from upstream
马上明白是超时时间太短。默认 proxy_read_timeout 是60秒,报表导出要90秒。
怎么解决:
location /report/ {
proxy_pass http://backend_servers;
proxy_read_timeout 120s; # 给报表导出加长时间
}
⚠️ 注意: 不要全局调大超时时间。只有确实需要长时间处理的接口才单独配,否则一个慢接口会拖住所有请求。
这个报错比较特殊。它不是Nginx主动报的,是客户端主动断开连接时Nginx记录下来的。
本质: 用户发请求给Nginx,Nginx转给后端,后端还在处理,用户等不及关了浏览器/点了取消。
常见场景:
499是不是问题?
怎么排查:
看Nginx access.log,统计499的比例:
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
如果499很多,同时504也很多,说明后端太慢。如果只有499没有504,可能是用户网络问题。
403相对好排查,就是Nginx没有权限读这个文件,或者配置不允许访问。
常见原因:
chmod 755chown www-datasetenforce 0autoindex offdeny 指令
我遇到的一个真实案例:
配了一个新站点,html文件都放好了,访问就是403。查了半天,发现是SELinux在作怪。
临时关闭测试:
setenforce 0永久关闭(生产慎用):
vi /etc/selinux/config改SELINUX=disabled
上传大文件时遇到的经典报错。
本质: client_max_body_size 限制了请求体大小,默认是1M。
怎么解决:
client_max_body_size 100M;
⚠️ 注意: 只配Nginx不够,后端也要配。比如PHP要改
upload_max_filesize和post_max_size。
400相对少见,但遇到就很头疼,因为Nginx给的提示很少。
常见原因:
large_client_header_buffers
排查方法:
error_log /var/log/nginx/error.log debug;
然后看error.log里有没有具体提示。
上周同事跑过来说:“网站502了,帮我看看。”
我按路线图走了一遍:
第1步: 看Nginx error.log
connect() failed (111: Connection refused) while connecting to upstream“Connection refused” = 后端端口没监听
第2步: 检查后端服务
ps aux | grep java(没输出)
第3步: 启动服务
systemctl start myapp
curl localhost:8080(通了)
5分钟搞定。 同事说他自己折腾了半小时。
排查路线图的价值就在这里——不慌,一步一步来,10分钟内一定能定位到问题层。
psclient_max_body_sizeroot 和 try_files
Nginx报错这件事,说白了就是学会看日志 + 知道每个报错对应哪一层。
我最开始遇到报错就慌,后来发现80%的问题都在几张表里。现在遇到报错,第一件事不是重启,而是去看error.log——日志里90%的情况已经告诉你答案了。
阅读原文:原文链接