Ubuntu 下 Nginx 出现 502 的排查与修复
一、快速判断与定位
- 含义:502 Bad Gateway 表示 Nginx 作为反向代理/网关,从上游(如 PHP-FPM、Node.js、Gunicorn)收到了无效响应或无法建立有效连接。优先查看 /var/log/nginx/error.log 获取具体错误关键词。
- 三步到位:
- 查看错误日志
tail -f /var/log/nginx/error.log
- 验证配置语法
sudo nginx -t
- 检查上游是否在服务
- PHP-FPM:systemctl status php-fpm;或检测端口/套接字:ss -lntp | grep :9000 或 ls /run/php/
- 反向代理:curl http://127.0.0.1:端口/健康检查
常见日志关键词与含义:
- connect() failed (111: Connection refused) → 上游未启动/端口不对
- connect() to unix:/run/…sock failed (2: No such file or directory) → 套接字文件不存在/路径不一致
- upstream timed out (110: Connection timed out) → 上游响应慢或超时过短
以上步骤与日志解读可快速锁定是“上游未起”“路径/端口不一致”还是“超时/资源”问题。
二、按场景修复
- PHP-FPM 场景
- 套接字通信:确认 PHP-FPM 的 listen 与 Nginx 的 fastcgi_pass 一致(同为 unix:/run/php/…sock 或同为 127.0.0.1:9000),路径不一致会直接 502。
- 权限与属主:在 /etc/php/*/fpm/pool.d/www.conf 中设置
listen.owner = www-data;listen.group = www-data;listen.mode = 0660
并确保 socket 所在目录对 www-data 可读写。
- 启动与重载:systemctl restart php-fpm;sudo nginx -s reload。
- 反向代理场景(Node.js/Gunicorn 等)
- 服务状态:systemctl status your-app(如 gunicorn);若用 Unix 套接字,确认进程已创建 .sock 文件且路径与 proxy_pass 完全一致。
- 连通性:ss -lntp | grep :端口 或 curl http://127.0.0.1:端口/health。
- 防火墙/安全组:ufw status;iptables -L -n;云主机安全组放通对应端口。
- 静态资源误代理导致 502/504
- 将 favicon.ico 等静态资源直接由 Nginx 处理,避免打到后端:
location = /favicon.ico { alias /path/to/static/favicon.ico; access_log off; log_not_found off; }
- 配置与路径细节
- 核对 root、alias、index、SCRIPT_FILENAME 等路径是否存在且可读。
- 使用 nginx -t 验证后再 reload。
以上修复要点覆盖“套接字/端口不一致”“权限不对”“上游未起/崩溃”“防火墙阻断”“静态资源误代理”等高发根因。
三、常见错误日志与对应修复
| 错误日志关键词 |
含义 |
快速修复 |
| connect() failed (111: Connection refused) |
上游未启动/端口不对 |
启动上游;核对 fastcgi_pass/proxy_pass 地址与端口 |
| connect() to unix:/run/…sock failed (2: No such file or directory) |
套接字不存在/路径不一致 |
统一 Nginx 与上游的 socket 路径;确认上游已创建 socket |
| upstream timed out (110: Connection timed out) |
上游响应慢/超时过短 |
适当增大 proxy_connect_timeout / proxy_read_timeout |
| Permission denied |
文件/目录/套接字权限不足 |
chown/chmod 正确属主与权限;核对 listen.owner/group/mode |
| no live upstreams while connecting to upstream |
upstream 列表为空/全部宕机 |
检查 upstream 配置与后端健康状态 |
| 以上对应关系可显著提升定位效率。 |
|
|
四、配置示例
- PHP-FPM(Unix 套接字)
- Nginx:
location ~ .php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php8.1-fpm.sock; }
- PHP-FPM(/etc/php/8.1/fpm/pool.d/www.conf):
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data;listen.group = www-data;listen.mode = 0660
- 反向代理(Gunicorn/Node 等)
- Nginx:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
修改后执行:sudo nginx -t && sudo systemctl reload nginx;上游变更后重启上游服务。
五、仍未解决时的进阶排查
- 资源与系统限制:free -h、top、ulimit -n 检查内存、CPU、文件描述符是否耗尽。
- 深入跟踪:
- strace 跟踪 Nginx worker:strace -p -s 1024 -e trace=file,network
- 动态观察错误关键词:strace -f $(pgrep nginx | sed ‘s/^/-p /’) 2>&1 | grep -E ‘ECONNREFUSED|EPERM’
- 安全模块:getenforce(SELinux)或 aa-status(AppArmor),必要时临时 setenforce 0 验证是否为策略阻断(验证后请恢复为 enforcing)。
这些手段可帮助发现“进程崩溃、资源枯竭、策略拦截”等深层原因。