You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gunicorn+Nginx报'Resource temporarily unavailable'及Worker挂死调试求助

问题分析与解决方案

环境与问题概述

  • 部署架构:Beanstalk Docker环境,采用gunicorn + supervisor + nginx部署Django应用
  • 实例规格:c6a.large,单实例负载约1700请求/分钟
  • 当前问题:
    • supervisor显示gunicorn处于运行状态,但所有请求返回Nginx 502错误
    • 无流量时gunicorn进程也无法自行恢复,期望supervisor能自动重启无法响应的gunicorn进程
  • Nginx错误日志核心提示:connect() to unix:/run/django_app.sock failed (11: Resource temporarily unavailable)

Nginx配置

server_tokens off;

upstream wsgi_server {
  # fail_timeout=0 means we always retry an upstream even if it failed
  # to return a good HTTP response (in case the Unicorn master nukes a
  # single worker for timing out).

  server unix:/run/django_app.sock fail_timeout=0;
}

server {
  location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Protocol $http_x_forwarded_proto;
      proxy_redirect off;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Scheme $scheme;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_connect_timeout 60s;
      proxy_read_timeout 60s;
      proxy_pass http://wsgi_server;
  }
}

一、解决502错误与supervisor自动重启配置

1. 502错误根因定位

日志里的Resource temporarily unavailable,大概率是两种情况:

  • gunicorn所有worker进程挂死/阻塞,无法处理新请求
  • Unix Socket的监听队列被占满,新请求无法进入

supervisor只监控进程是否存活,不会检测进程是否能正常响应,所以会显示gunicorn运行但实际无服务能力。

2. 调整gunicorn配置

针对高负载和worker阻塞问题,优化参数:

  • worker数量:c6a.large是2核4G,设置workers = 2*CPU核心数+1(即5个),匹配硬件资源
  • 自动重启机制:添加max_requests=1000和max_requests_jitter=200,让worker处理一定请求后自动重启,避免内存泄漏或长期阻塞
  • 超时控制:设置timeout=30(比Nginx的proxy_read_timeout短10秒),让gunicorn主动杀死超时worker并重建

示例启动命令:

gunicorn --workers 5 --worker-connections 2000 --timeout 30 --max-requests 1000 --max-requests-jitter 200 --bind unix:/run/django_app.sock your_project.wsgi:application

3. 配置supervisor的智能监控

默认supervisor只看进程是否存在,需要增强监控逻辑:

  • 开启自动重启:在supervisor配置中添加autorestart=true,进程异常退出时自动重启
  • 延迟判定运行状态:设置startsecs=5,避免进程刚启动就被误判为正常
  • 记录日志:配置stdout_logfile和stderr_logfile,留存gunicorn运行日志便于排查
  • 自定义健康检查:写个简单脚本定期请求Django的健康接口(比如/health),连续失败就调用supervisorctl restart gunicorn,用cron或supervisor的eventlistener定期执行

示例supervisor配置片段:

[program:gunicorn]
command=/path/to/gunicorn --workers 5 --worker-connections 2000 --timeout 30 --max-requests 1000 --max-requests-jitter 200 --bind unix:/run/django_app.sock your_project.wsgi:application
directory=/path/to/your/project
user=www-data
autostart=true
autorestart=true
startsecs=5
stdout_logfile=/var/log/gunicorn_stdout.log
stderr_logfile=/var/log/gunicorn_stderr.log

4. 优化Nginx的Socket配置

  • 增大Socket监听队列:在upstream中添加backlog=8192,避免高负载下队列溢出
  • 修正Socket权限:确保gunicorn和Nginx运行用户属于同一组,或在gunicorn启动参数中加--chmod=770,保证Nginx能读写Socket

修改后的upstream配置:

upstream wsgi_server {
  server unix:/run/django_app.sock fail_timeout=0 backlog=8192;
}

二、调试挂死的gunicorn worker

1. 开启gunicorn详细日志

启动时添加--log-level debug,或在配置文件中设置loglevel=debug,记录worker的请求处理细节、异常栈信息。

2. 用gdb分析进程调用栈

  • 找到挂死的worker PID:ps aux | grep gunicorn(子进程是worker,主进程是master)
  • 附加进程:gdb /path/to/gunicorn <worker_pid>
  • 查看调用栈:thread apply all bt,直接定位worker阻塞的代码位置(比如数据库查询、IO操作、死循环)

3. 使用Python追踪工具

  • trace模块:实时追踪进程执行代码:python -m trace -t -p <worker_pid>,找到阻塞的代码行
  • py-spy:安装后执行py-spy top --pid <worker_pid>,可视化显示进程CPU使用和函数调用占比,快速定位性能瓶颈

4. 检查系统资源

  • 内存:free -h,确认是否内存耗尽导致worker被OOM杀死或阻塞
  • 文件句柄:lsof -p <worker_pid>,检查是否存在未关闭的数据库连接、文件句柄泄漏
  • CPU负载:top -p <worker_pid>,看worker是CPU密集型阻塞还是完全无响应

5. 启用Django请求日志

在settings.py中配置详细请求日志,记录每个请求的处理时间、视图函数、异常信息:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {'class': 'logging.StreamHandler'},
    },
    'loggers': {
        'django.request': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

内容的提问来源于stack exchange,提问作者pratik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:45:32