Nginx反向代理Django出现502 Bad Gateway错误怎么排查?

文章导读
Nginx 返回 502 Bad Gateway 说明 Nginx 作为网关收到了上游 Django 服务的无效响应或无法连接。排查重点在于确认 Django 应用进程是否存活、Nginx 配置的上游地址是否正确以及文件权限是否允许通信。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Nginx 返回 502 Bad Gateway 说明 Nginx 作为网关收到了上游 Django 服务的无效响应或无法连接。排查重点在于确认 Django 应用进程是否存活、Nginx 配置的上游地址是否正确以及文件权限是否允许通信。

先说结论:502 错误通常由上游服务宕机、通信 socket 权限不足或配置超时导致,优先检查应用进程状态和错误日志。

  • 先确认:Django 后端服务(如 Gunicorn/uWSGI)是否正在运行且监听指定端口或 Socket 文件。
  • 先处理:修复 Nginx 与后端之间的权限问题或调整 proxy_pass 配置指向正确的上游地址。
  • 再验证:通过 curl 请求测试接口并观察 Nginx 错误日志是否不再出现 upstream 相关报错。

命令速用版

以下命令用于快速检查服务状态和日志,适用于大多数 Linux 发行版。

# 检查 Django 后端服务状态(以 gunicorn 为例)
systemctl status gunicorn

# 检查 Nginx 配置语法
nginx -t

# 查看 Nginx 错误日志最后 50 行
tail -n 50 /var/log/nginx/error.log

# 测试本地后端是否可达(替换为实际端口或 socket)
curl -I http://127.0.0.1:8000

为什么会这样

502 Bad Gateway 表示 Nginx 无法从上游服务器获得有效响应。

Nginx 作为反向代理,负责将客户端请求转发给后端的 Django 应用服务器(如 Gunicorn、uWSGI 或 Daphne)。当 Nginx 尝试连接上游地址时,如果连接被拒绝、连接重置、上游进程崩溃或返回了不符合 HTTP 协议的数据,Nginx 就会向客户端返回 502 状态码。这通常不是 Nginx 本身的问题,而是后端应用服务或两者之间的通信链路出了问题。

分步处理

按顺序执行以下步骤,定位具体故障点。

步骤 1:检查后端服务进程

确认 Django 应用服务器是否正在运行。如果使用 systemd 管理,使用 status 命令查看。如果进程处于 inactive 或 failed 状态,尝试重启服务。

systemctl status gunicorn
systemctl restart gunicorn

步骤 2:检查 Nginx 错误日志

Nginx 错误日志会记录具体的 upstream 错误原因,如 connect() failed 或 permission denied。

tail -f /var/log/nginx/error.log

常见日志信息包括 "connect() failed (111: Connection refused)" 或 "permission denied"。

步骤 3:核对 Socket 或端口配置

检查 Nginx 配置文件中 proxy_pass 指向的地址是否与后端服务监听的地址一致。如果使用 Unix Socket,确保路径完全匹配。

Nginx反向代理Django出现502 Bad Gateway错误怎么排查?
# Nginx 配置示例
location / {
    proxy_pass http://unix:/run/gunicorn.sock;
    # 或 proxy_pass http://127.0.0.1:8000;
}

步骤 4:检查文件权限

如果使用 Unix Socket,Nginx worker 进程用户(通常是 www-data 或 nginx)必须有权读写该 Socket 文件。检查 Socket 文件所属组和权限。

ls -l /run/gunicorn.sock
chown www-data:www-data /run/gunicorn.sock
chmod 660 /run/gunicorn.sock

怎么验证是否生效

完成修复后,通过以下方式确认服务恢复正常。

1. 状态码检查

使用 curl 请求网站,确认返回状态码为 200 而不是 502。

curl -I https://your-domain.com

2. 日志观察

持续观察 Nginx 错误日志,确认在发起请求时不再出现 upstream 相关的报错信息。

3. 页面内容验证

访问 Django 应用的具体页面,确认动态内容正常加载,没有白屏或错误提示。

常见坑

  • SELinux 限制:在开启 SELinux 的系统(如 CentOS/RHEL)上,即使文件权限正确,SELinux 策略也可能阻止 Nginx 连接网络或 Socket,需检查 setsebool 设置。
  • 用户不一致:后端服务以 root 运行创建 Socket,Nginx 以 www-data 运行,导致无权访问,需统一运行用户或调整组权限。
  • 超时设置过短:Django 处理请求时间超过 Nginx 默认超时时间可能导致 504,但配置错误导致的立即断开常表现为 502。
  • Socket 路径变更:后端服务重启后 Socket 文件路径可能变化,需确保服务配置中 Socket 绑定路径固定。

常见问题

502 和 504 错误有什么区别?

502 表示上游服务器返回了无效响应或连接失败,504 表示上游服务器响应超时。502 通常是服务挂了或权限不对,504 通常是处理太慢。

使用 TCP 端口还是 Unix Socket 更好?

同一台服务器上 Unix Socket 性能略高且权限控制更细,跨服务器部署必须使用 TCP 端口。排查 502 时 Socket 权限问题更常见。

修改配置后需要重启 Nginx 吗?

修改 Nginx 配置文件后必须重载配置才能生效,使用 nginx -s reload 命令,无需完全停止服务。

参考来源

  • Nginx Official Documentation, "ngx_http_proxy_module", https://nginx.org/en/docs/http/ngx_http_proxy_module.html
  • Gunicorn Documentation, "Deployment", https://docs.gunicorn.org/en/stable/deploy.html
  • Django Project Documentation, "How to deploy with WSGI", https://docs.djangoproject.com/en/stable/howto/deployment/wsgi/gunicorn/