Nginx 出现 502 错误,是搭建网站过程中最常见的问题之一。
很多人遇到 502 Bad Gateway,第一反应就是重启 Nginx、重启 PHP-FPM,甚至直接重启服务器。这样操作以后,网站可能暂时恢复,但过几个小时或者访问量一上来,502 又出现了。
说白了,重启只是恢复服务,没有找到根因。
Nginx 返回 502,通常不是 Nginx 自己不能运行,而是它没有从 PHP-FPM、Node.js、Java、Python 等上游服务拿到有效响应。
所以,排查 Nginx 502 错误的正确思路不是“把所有服务重启一遍”,而是先看错误日志,根据日志判断上游服务为什么没有正常响应。

Nginx 出现 502 Bad Gateway 是什么意思?
一个使用 Nginx 的网站,常见请求流程是:
浏览器
→ Nginx
→ PHP-FPM 或其他后端程序
→ 数据库
→ 返回页面
Nginx 可以直接处理图片、CSS、JavaScript 等静态文件,但遇到 PHP 页面或者反向代理请求时,需要把请求交给上游服务处理。
例如:
- WordPress 通常交给 PHP-FPM;
- Node.js 网站交给 Node 服务;
- Java 网站交给 Tomcat、Spring Boot 等服务;
- Python 网站交给 Gunicorn、uWSGI 等服务。
如果 Nginx 能接收到浏览器请求,却无法连接上游服务,或者上游服务没有返回有效内容,Nginx 就可能返回:
502 Bad Gateway
所以,502 只是结果。
真正的问题一般发生在 Nginx 后面的服务链路中。
先判断是哪一种 Nginx 502 错误
在执行命令之前,先观察故障表现。
不同的表现,排查方向完全不同。
全站持续出现 502
如果首页、文章页、后台全部打不开,而且每次访问都是 502,优先检查:
- PHP-FPM 是否停止;
- Node.js、Java、Python 等后端服务是否停止;
- Nginx 上游地址是否写错;
- 后端端口是否没有监听;
- PHP-FPM Socket 文件是否不存在;
- Nginx 是否没有权限访问 Socket。
这种情况通常是固定配置错误,或者上游服务已经完全退出。
只有部分页面出现 502
如果首页正常,但后台、导入页面、搜索页面或者某个接口出现 502,问题通常集中在具体程序上。
常见原因包括:
- 某个 PHP 脚本执行时间过长;
- WordPress 插件或主题报错;
- 数据库查询太慢;
- 外部接口迟迟没有响应;
- 上传、备份和导入任务超时;
- 单个请求占用内存过高。
这时不应该优先改全局配置,而应该找到具体出错的页面和请求。
高峰期偶发 502
如果平时正常,访问量一高就出现 502,重点排查:
- PHP-FPM 进程池已满;
- 后端应用并发能力不足;
- MySQL 查询变慢;
- 服务器内存耗尽;
- 应用进程被 OOM Killer 杀死;
- 爬虫、攻击请求或突发流量过多。
这种问题最容易被重启掩盖。
重启以后进程、连接和内存暂时恢复,看起来像修好了,实际上流量一回来,问题还会重现。
出现 502 后先保存现场,不要急着重启
排查服务器故障时,应该先看现场,再考虑要不要重启。
因为服务一旦重启,进程状态、内存占用、连接数量和部分临时日志都可能发生变化。
先记录以下信息:
- 502 出现的具体时间;
- 出错的域名和页面;
- 是持续出现还是偶发;
- 前台和后台是否都受影响;
- 最近有没有升级 PHP、插件或程序;
- 最近有没有修改 Nginx 配置;
- 当时 CPU、内存和磁盘是否异常。
然后执行:
date
uptime
free -h
df -h
top
检查 Nginx 状态:
systemctl status nginx --no-pager
检查 Nginx 配置:
nginx -t
使用 curl 复现请求:
curl -I https://example.com
如果需要查看更完整的连接过程,可以使用:
curl -v https://example.com
这些信息看起来很基础,但它们能快速判断问题是在 Nginx、上游程序,还是服务器资源层面。
第一步:查看 Nginx 错误日志
解决 Nginx 502 错误,最有价值的信息不是浏览器里的“Bad Gateway”,而是 Nginx 错误日志。
常见日志路径为:
/var/log/nginx/error.log
查看最近 100 行:
tail -n 100 /var/log/nginx/error.log
实时观察日志:
tail -f /var/log/nginx/error.log
如果网站配置了独立日志,需要先查找实际路径:
nginx -T 2>/dev/null | grep error_log
宝塔、1Panel 或自定义环境可能把日志放在网站目录或面板指定目录中,不要认定日志一定在默认位置。
可以筛选 502 相关日志:
grep -iE "upstream|connect|timed out|prematurely|permission denied" /var/log/nginx/error.log | tail -n 100
常见提示主要有:
Connection refused
No such file or directory
Permission denied
upstream timed out
upstream prematurely closed connection
recv() failed
upstream sent too big header
看到哪一种提示,就沿着对应方向排查。
这才是最快的办法。
Connection refused:上游服务没有监听
常见日志如下:
connect() failed (111: Connection refused) while connecting to upstream
这段日志的意思是:Nginx 找到了上游地址,但连接目标端口时被拒绝了。
通常有四种原因:
- 后端服务没有启动;
- 后端服务启动失败;
- Nginx 配置的端口不对;
- 服务监听的地址与 Nginx 请求的地址不一致。
先从 Nginx 配置中找到上游地址:
nginx -T 2>/dev/null | grep -E "proxy_pass|fastcgi_pass"
可能看到:
proxy_pass http://127.0.0.1:3000;
接着检查端口:
ss -lntp | grep 3000
如果没有任何结果,说明没有程序监听 3000 端口。
继续检查应用状态。例如 Node.js 使用 PM2:
pm2 status
pm2 logs
使用 systemd 管理的服务:
systemctl status 服务名称 --no-pager
journalctl -u 服务名称 -n 100 --no-pager
还可以绕过 Nginx,直接请求后端:
curl -v http://127.0.0.1:3000
如果直连后端也失败,问题就在应用服务,不在 Nginx。
检查监听地址是否一致
有时候应用明明启动了,端口也没写错,但 Nginx 还是连接失败。
例如应用只监听:
127.0.0.1:3000
Nginx 却连接:
服务器内网IP:3000
或者应用只监听 IPv6:
[::1]:3000
Nginx 却连接 IPv4:
127.0.0.1:3000
通过下面的命令确认实际监听地址:
ss -lntp
然后统一应用监听地址与 Nginx 的 proxy_pass 配置。
修改完成后检查并重载 Nginx:
nginx -t
systemctl reload nginx
No such file or directory:PHP-FPM Socket 路径错误
WordPress、Typecho 等 PHP 网站出现全站 502 时,经常能看到:
connect() to unix:/run/php/php-fpm.sock failed
No such file or directory
这说明 Nginx 配置了一个 Unix Socket,但对应文件不存在。
常见原因包括:
- PHP-FPM 没有启动;
- PHP 升级后 Socket 路径变了;
- Nginx 仍然连接旧版本 PHP;
- PHP-FPM 的
listen配置与 Nginx 不一致; - Socket 所在目录没有成功创建。
先查看 PHP-FPM 状态:
systemctl list-units --type=service | grep -E "php.*fpm"
然后检查具体版本,例如:
systemctl status php8.2-fpm --no-pager
查找现有 Socket:
find /run /var/run -type s -name "*php*" 2>/dev/null
可能找到:
/run/php/php8.2-fpm.sock
再检查 Nginx 配置:
nginx -T 2>/dev/null | grep fastcgi_pass
如果 Nginx 写的是:
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
而实际文件是:
/run/php/php8.2-fpm.sock
根因就很清楚了。
把 Nginx 配置改成实际路径:
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
或者检查 PHP-FPM 进程池配置中的 listen:
grep -R "^listen =" /etc/php/*/fpm/pool.d/ 2>/dev/null
修改完成后分别检查配置:
nginx -t
php-fpm -t
部分系统需要带版本执行,例如:
php-fpm8.2 -t
最后重启 PHP-FPM 并重载 Nginx:
systemctl restart php8.2-fpm
systemctl reload nginx
Permission denied:Nginx 没有权限访问 Socket
另一种常见日志是:
connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied)
Socket 文件存在,PHP-FPM 也在运行,但 Nginx 没有权限连接。
先确认 Nginx Worker 用户:
grep "^user" /etc/nginx/nginx.conf
常见用户包括:
www-data
nginx
www
再查看 PHP-FPM 进程池配置:
grep -E "^(user|group|listen|listen.owner|listen.group|listen.mode)" /etc/php/8.2/fpm/pool.d/www.conf
合理配置可能类似:
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
查看当前 Socket 权限:
ls -l /run/php/php8.2-fpm.sock
还要检查父目录权限:
namei -l /run/php/php8.2-fpm.sock
很多人遇到权限错误,直接执行:
chmod 777 Socket文件
这种处理不推荐。
因为 PHP-FPM 重启后 Socket 会重新创建,权限可能恢复原状,而且 777 会扩大不必要的访问权限。
正确做法是修改 PHP-FPM 的 listen.owner、listen.group 和 listen.mode,然后重启 PHP-FPM。
如果文件权限看起来都正常,还要检查 SELinux:
getenforce
查看近期拦截记录:
ausearch -m AVC -ts recent
不要为了省事直接永久关闭 SELinux。先确认具体拦截原因,再根据实际服务和安全策略处理。
upstream timed out:后端响应时间太长
常见日志如下:
upstream timed out while reading response header from upstream
它的意思不是 Nginx 连不上后端,而是连接以后,等待太久仍然没有拿到响应。
常见场景包括:
- WordPress 插件执行慢;
- MySQL 查询耗时过长;
- 外部 API 没有及时返回;
- 网站正在备份或导入大量数据;
- PHP 脚本死循环;
- 后端服务线程阻塞;
- 服务器 CPU 或磁盘负载过高。
PHP 网站常见超时参数有:
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
反向代理常见参数有:
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
PHP 自身还可能设置:
max_execution_time = 60
PHP-FPM 进程池里可能存在:
request_terminate_timeout = 60s
这里要注意一个很容易犯的错误:看到超时,就把所有参数改成 600 秒。
如果一个正常页面需要执行 10 分钟,本身就不正常。
延长超时时间适合确实需要较长时间完成的导入、导出等任务,但不能代替程序优化。
正确的排查顺序是:
- 找到具体超时的 URL;
- 查看 PHP 或应用日志;
- 检查数据库慢查询;
- 检查是否调用了外部接口;
- 检查 CPU、内存和磁盘状态;
- 确认业务确实需要后,再合理调整超时。
对于备份、视频处理、大文件导入等耗时任务,更好的方式是交给队列或后台任务处理,而不是让一个 Web 请求长期占用 PHP-FPM 进程。
upstream prematurely closed connection:后端提前断开
常见日志:
upstream prematurely closed connection while reading response header from upstream
这说明 Nginx 已经连接到后端,但后端在返回完整响应之前关闭了连接。
可能的原因有:
- PHP Fatal Error;
- PHP 内存超限;
- PHP-FPM 主动终止请求;
- Node.js、Java 或 Python 应用崩溃;
- 进程被 OOM Killer 杀死;
- 应用自身设置了更短的超时;
- 程序返回了异常响应。
PHP 网站先检查 PHP-FPM 日志:
journalctl -u php8.2-fpm -n 200 --no-pager
检查 PHP 错误日志:
grep -iE "fatal|memory|terminated|child exited" /var/log/php* 2>/dev/null
如果是 WordPress,还可以检查:
wp-content/debug.log
Node.js、Java、Python 等应用则需要查看应用自己的异常堆栈和进程管理日志。
还要检查 OOM:
dmesg -T | grep -iE "out of memory|killed process|oom"
或者:
journalctl -k | grep -iE "out of memory|killed process|oom"
如果日志显示 PHP、MySQL 或应用进程被系统杀死,根因就是内存不足,而不是 Nginx 超时。
PHP-FPM 进程池耗尽导致 502
高峰期偶发 502,PHP-FPM 进程池耗尽是一个很常见的原因。
日志里可能出现:
server reached pm.max_children setting
pm.max_children 控制 PHP-FPM 最多可以同时运行多少个工作进程。
假设配置为:
pm.max_children = 5
当 5 个进程都在处理请求时,新请求只能等待。如果请求持续堆积,最终就可能超时或报错。
但解决方法不是简单把 5 改成 50。
因为每个 PHP-FPM 进程都要占用内存。假设单个进程平均占用 80MB:
80MB × 50 = 4000MB
在一台 2G 服务器上,这种配置反而会直接触发 OOM。
查看 PHP-FPM 进程内存
可以执行:
ps --no-headers -o rss,cmd -C php-fpm | awk '{sum+=$1; count++} END {if(count>0) print "进程数:",count,"平均RSS:",sum/count/1024,"MB","总RSS:",sum/1024,"MB"}'
部分系统中的进程名包含版本号,可以先查看:
ps aux | grep "[p]hp-fpm"
然后根据以下思路估算:
可分配给 PHP-FPM 的内存 ÷ 单个进程平均内存
例如,服务器能给 PHP-FPM 留出 600MB,单个进程平均占用 70MB:
600 ÷ 70 ≈ 8
考虑安全空间,pm.max_children 可以先设置为 6 或 7,再根据实际队列和负载调整。
PHP-FPM 三种管理模式
常见模式包括:
pm = static
pm = dynamic
pm = ondemand
static 会固定创建指定数量的进程,适合内存充足、流量稳定的环境。
dynamic 会根据请求增减进程,适合大多数网站。
ondemand 在有请求时创建进程,空闲后退出,适合访问量不高的小内存服务器。
小型网站可以参考:
pm = ondemand
pm.max_children = 6
pm.process_idle_timeout = 10s
pm.max_requests = 500
这只是参考配置,不能不看服务器内存就直接照抄。
pm.max_requests 可以让工作进程处理一定数量的请求后重新创建,对第三方扩展或程序存在缓慢内存增长的情况有一定帮助。
开启 PHP-FPM 慢日志
如果进程长期被占用,需要找到具体是哪个脚本执行太慢。
进程池中可以配置:
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log
日志目录需要提前存在,并保证 PHP-FPM 有权限写入。
开启后,超过指定时间的请求会记录调用信息。这样才能判断到底是 WordPress 插件、主题代码、数据库查询,还是外部接口拖慢了 PHP。
服务器内存耗尽导致 Nginx 502
服务器内存不足时,Linux 可能强制杀掉 PHP-FPM、MySQL 或后端应用。
先执行:
free -h
重点看:
available是否过低;- Swap 是否持续增加;
- 是否已经没有可用内存。
按内存排序进程:
ps aux --sort=-%mem | head -20
检查 OOM:
dmesg -T | grep -iE "oom|killed process|out of memory"
还可以查看:
journalctl -k --since "1 hour ago" | grep -iE "oom|killed process|out of memory"
如果日志中明确显示某个应用被杀,就继续排查它为什么占用大量内存。
常见原因包括:
- PHP-FPM 进程数量过多;
- 单个 PHP 请求内存过高;
- MySQL 缓存设置过大;
- Node.js 或 Java 堆内存失控;
- 插件任务并发执行;
- 容器设置了过低的内存限制。
不要忘记检查磁盘:
df -h
df -i
磁盘空间或 inode 耗尽,也可能导致应用无法写入日志、缓存、Session 和临时文件,随后异常退出。
Swap 可以作为兜底,但不能替代内存优化。如果服务器长期大量使用 Swap,网站通常会越来越慢。
数据库过慢也会间接造成 502
Nginx 日志只会告诉你上游响应慢,却不一定告诉你为什么慢。
很多时候,PHP-FPM 进程本身没有问题,它只是在等待 MySQL。
先检查数据库状态:
systemctl status mysql --no-pager
MariaDB 环境可能是:
systemctl status mariadb --no-pager
查看当前连接:
SHOW PROCESSLIST;
查看更完整的信息:
SHOW FULL PROCESSLIST;
如果大量查询长期处于以下状态:
Locked
Sending data
Copying to tmp table
Waiting for table metadata lock
就需要进一步排查慢查询、索引、锁等待和长事务。
还可以检查连接数量:
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
SHOW VARIABLES LIKE 'max_connections';
对于 WordPress 网站,重点排查:
- 搜索和相关文章插件;
- 统计插件;
- WooCommerce 后台任务;
wp_options自动加载数据过大;- WP-Cron 任务堆积;
- 没有索引的自定义查询;
- 插件重复请求外部接口。
调大 Nginx 的 fastcgi_read_timeout 只能让 Nginx 多等一会儿,不会让 SQL 自动变快。
这才是最关键的区别。
upstream sent too big header 怎么解决?
常见日志:
upstream sent too big header while reading response header from upstream
它表示上游返回的响应头超过了 Nginx 当前缓冲区容量。
常见原因包括:
- Cookie 过多或体积过大;
- Session 信息异常;
- 多次重定向不断写入 Cookie;
- 应用返回了很大的响应头;
- 登录插件或认证程序写入大量数据。
PHP-FPM 场景可以调整:
fastcgi_buffer_size 32k;
fastcgi_buffers 8 16k;
反向代理场景可以调整:
proxy_buffer_size 32k;
proxy_buffers 8 16k;
不同网站需要的大小不同,不要机械复制。
在调大 Buffer 之前,先使用浏览器开发者工具或 curl 查看响应头:
curl -I https://example.com
如果发现 Cookie 异常大,应该先清理程序中的异常 Cookie 和 Session 逻辑。
调大 Buffer 是允许 Nginx 接受更大的响应头,但不代表上游返回巨大响应头就是合理的。
Docker 环境出现 Nginx 502 怎么排查?
Docker 环境的 502 经常不是程序坏了,而是对网络关系理解错了。
先查看容器:
docker ps -a
检查容器是否不断重启:
docker inspect 容器名称 --format '{{.State.Status}} {{.State.Restarting}} {{.State.OOMKilled}}'
查看日志:
docker logs --tail 200 容器名称
容器里的 127.0.0.1 不是宿主机
如果 Nginx 和后端应用运行在不同容器中,在 Nginx 容器里写:
proxy_pass http://127.0.0.1:3000;
通常会连接 Nginx 容器自身,而不是另一个应用容器。
同一个 Docker 网络中,一般应该通过服务名访问:
proxy_pass http://app:3000;
检查容器网络:
docker network ls
docker network inspect 网络名称
进入 Nginx 容器测试:
docker exec -it nginx容器 sh
然后从容器内部请求后端:
curl http://app:3000
如果容器不断重启,还要检查:
- 环境变量是否缺失;
- 数据库是否能连接;
- 启动命令是否报错;
- 健康检查是否失败;
- 容器是否因为内存限制被杀。
Docker 里的 502,本质上仍然是 Nginx 没拿到上游响应,只是上游地址变成了容器网络中的服务。
Node.js、Java、Python 反向代理出现 502 的排查顺序
非 PHP 网站可以使用下面这套通用流程。
1. 找到 proxy_pass
nginx -T 2>/dev/null | grep proxy_pass
例如:
proxy_pass http://127.0.0.1:8080;
2. 检查端口
ss -lntp | grep 8080
3. 绕过 Nginx 直连后端
curl -v http://127.0.0.1:8080
4. 检查应用进程
ps aux | grep 应用名称
5. 查看应用日志
使用 systemd:
journalctl -u 服务名称 -n 200 --no-pager
使用 PM2:
pm2 status
pm2 logs --lines 200
使用 Docker:
docker logs --tail 200 容器名称
6. 检查应用依赖
包括:
- 数据库;
- Redis;
- 消息队列;
- 外部 API;
- 文件存储;
- DNS 解析。
如果后端端口能访问,但通过 Nginx 出现 502,再检查:
proxy_pass地址是否正确;- HTTP 和 HTTPS 协议是否写反;
- 响应头是否过大;
- Nginx 是否提前超时;
- WebSocket 请求头是否正确配置。
修复后怎么验证问题真的解决了?
完成修改后,先检查 Nginx 配置:
nginx -t
确认没有错误,再平滑重载:
systemctl reload nginx
如果修改了 PHP-FPM,则检查并重启对应服务:
systemctl restart php8.2-fpm
systemctl status php8.2-fpm --no-pager
然后使用 curl 查看状态码和耗时:
curl -sS -o /dev/null \
-w "状态码:%{http_code} 总耗时:%{time_total}s\n" \
https://example.com
在 Linux 服务器上连续请求测试:
for i in $(seq 1 10); do
curl -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://example.com
done
如果在本地 PowerShell 中测试,可以使用:
for ($i = 1; $i -le 10; $i++) {
curl.exe -s -o NUL -w "%{http_code} %{time_total}`n" https://example.com
}
同时观察错误日志:
tail -f /var/log/nginx/error.log
还要实际访问之前出问题的功能,例如:
- WordPress 后台;
- 登录页面;
- 文件上传;
- 数据导入;
- 搜索页面;
- API 接口;
- 订单或支付页面。
页面能打开一次,不代表问题已经根治。
如果原来是高峰期偶发故障,就要继续观察访问高峰时的 PHP-FPM 进程、内存、队列和错误日志。
如何防止 Nginx 502 再次出现?
处理完故障以后,最好补上监控和保护措施。
配置服务自动恢复
使用 systemd 管理后端程序时,可以根据业务情况设置:
Restart=on-failure
RestartSec=5
这能在程序异常退出后自动拉起服务。
不过自动重启只是容错,不是修复程序崩溃的根因。
记录上游响应时间
可以在 Nginx 日志格式中加入:
$request_time
$upstream_connect_time
$upstream_header_time
$upstream_response_time
$upstream_status
这样出现慢请求时,能快速判断时间消耗在 Nginx、连接过程还是后端处理阶段。
开启慢请求和慢查询日志
对于 PHP 网站,开启 PHP-FPM Slowlog。
对于 MySQL,合理开启慢查询日志。
对于 Node.js、Java 和 Python 应用,记录接口耗时、异常堆栈和依赖调用时间。
没有这些日志,下一次出现 502 时仍然只能猜。
监控服务器资源
至少监控:
- CPU 使用率;
- 系统负载;
- 可用内存;
- Swap 使用量;
- 磁盘空间;
- inode;
- PHP-FPM 进程数;
- 应用重启次数;
- 502 状态码数量;
- 上游响应时间。
如果只监控“网站能不能打开”,往往发现问题时已经晚了。
减少不必要的动态请求
可以通过以下方式减轻后端压力:
- 使用页面缓存;
- 使用 CDN;
- 限制异常爬虫;
- 保护登录和接口地址;
- 把耗时任务交给队列;
- 优化数据库查询;
- 避免高峰期执行备份和扫描任务。
缓存不是万能的,但它确实能减少大量重复进入 PHP 或应用程序的请求。
Nginx 502 错误快速排查表
| 错误日志 | 常见根因 | 优先检查 |
|---|---|---|
Connection refused |
后端未启动或端口错误 | 服务状态、监听端口、上游地址 |
No such file or directory |
PHP-FPM Socket 不存在 | PHP-FPM 状态、Socket 路径 |
Permission denied |
Nginx 无权访问 Socket | 用户、用户组、目录权限、SELinux |
upstream timed out |
后端响应过慢 | 程序日志、慢查询、外部接口 |
prematurely closed connection |
上游崩溃或主动终止 | 应用日志、PHP Fatal Error、OOM |
upstream sent too big header |
响应头过大 | Cookie、Session、Buffer |
pm.max_children |
PHP-FPM 进程池已满 | 单进程内存、进程数、慢请求 |
| 偶发 502 且服务被重启 | 内存或容器限制 | OOM 日志、内存、Swap |
| Docker 内部连接失败 | 容器地址或网络错误 | 服务名、Docker 网络、容器日志 |
Nginx 502 错误的正确排查顺序
最后总结一下,遇到 Nginx 502 错误,可以按照这条链路处理:
确认故障范围
→ 记录故障时间
→ 查看 Nginx 错误日志
→ 识别日志关键词
→ 找到 upstream 地址
→ 直连测试上游服务
→ 检查应用和系统日志
→ 修复端口、Socket、权限、程序或资源问题
→ 验证配置
→ 持续观察并增加监控
如果日志是 Connection refused,就去查服务和端口。
如果是 No such file,就去查 Socket 路径。
如果是 Permission denied,就去查用户和权限。
如果是 upstream timed out,就去查程序、数据库和外部接口。
如果应用被系统杀死,就去查内存和 OOM。
逻辑其实并不复杂。
Nginx 502 错误最麻烦的地方,不是它不能解决,而是很多人一开始就把方向搞错了。不断重启、反复增加超时时间、随手修改权限,最后配置越来越乱,真正的问题还在。
记住一句话:502 是上游没有正常回答 Nginx,不是答案本身。
先看日志,再根据证据处理。找到上游服务为什么停止、超时或崩溃,才算从根源解决问题。