fix: gunicorn.conf.py 从 sync 改为 gthread,修复全站卡死根因
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
37
deploy/audit-system.sh
Normal file
37
deploy/audit-system.sh
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 系统级排查:Gunicorn 是否双开、是否用了错误的 sync 配置
|
||||||
|
set -e
|
||||||
|
echo "========== Gunicorn 进程(看 worker_class / 是否双开)=========="
|
||||||
|
pgrep -af gunicorn || echo "无 gunicorn"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========== 8001 端口占用 =========="
|
||||||
|
ss -ltnp 2>/dev/null | grep 8001 || netstat -ltnp 2>/dev/null | grep 8001 || echo "8001 未监听"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========== systemd 实际启动命令 =========="
|
||||||
|
systemctl cat gunicorn-dianjing.service 2>/dev/null | grep -E '^ExecStart|^Environment' || echo "无 systemd service"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========== gunicorn.conf.py 关键项 =========="
|
||||||
|
CONF="/opt/1panel/apps/openresty/nginx/www/sites/43.142.166.152.443/django/gunicorn.conf.py"
|
||||||
|
if [ -f "$CONF" ]; then
|
||||||
|
grep -E 'worker_class|workers|threads|accesslog|errorlog|preload' "$CONF" | grep -v '^#'
|
||||||
|
else
|
||||||
|
echo "找不到 $CONF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========== 判定 =========="
|
||||||
|
NG=$(pgrep -cf 'gunicorn.*a_long_dianjing' 2>/dev/null || echo 0)
|
||||||
|
if [ "$NG" -gt 8 ]; then
|
||||||
|
echo ">>> 警告: gunicorn 进程过多($NG),可能 systemd + 1Panel 双开,必须只留 systemd"
|
||||||
|
fi
|
||||||
|
if grep -q 'worker_class.*sync' "$CONF" 2>/dev/null; then
|
||||||
|
echo ">>> 致命: gunicorn.conf.py 仍是 sync,全站会卡死,必须改为 gthread 并 restart"
|
||||||
|
fi
|
||||||
|
if grep -q 'accesslog.*"-' "$CONF" 2>/dev/null || grep -q "accesslog = '-'" "$CONF" 2>/dev/null; then
|
||||||
|
echo ">>> 致命: accesslog 输出到 stdout,会灌 journal 卡整机"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "正确做法: 1Panel 关闭 Python 自动管理 → git pull → bash deploy/safe-deploy.sh"
|
||||||
@@ -7,7 +7,7 @@ Type=simple
|
|||||||
User=root
|
User=root
|
||||||
Group=root
|
Group=root
|
||||||
WorkingDirectory=/opt/1panel/apps/openresty/nginx/www/sites/43.142.166.152.443/django
|
WorkingDirectory=/opt/1panel/apps/openresty/nginx/www/sites/43.142.166.152.443/django
|
||||||
ExecStart=/usr/local/bin/gunicorn --bind 127.0.0.1:8001 --workers 6 --threads 4 --worker-class gthread --timeout 120 --log-level warning --access-logfile /dev/null --error-logfile /tmp/gunicorn-error.log a_long_dianjing.wsgi:application
|
ExecStart=/usr/local/bin/gunicorn -c gunicorn.conf.py a_long_dianjing.wsgi:application
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=3
|
RestartSec=3
|
||||||
StandardOutput=null
|
StandardOutput=null
|
||||||
|
|||||||
@@ -1,52 +1,32 @@
|
|||||||
# /opt/1panel/apps/openresty/nginx/www/sites/43.142.166.152.443/django/gunicorn.conf.py
|
# Gunicorn 生产配置(systemd 与 1Panel 共用此文件,勿再手写冲突参数)
|
||||||
|
# 安装后: systemctl restart gunicorn-dianjing.service
|
||||||
|
|
||||||
# 绑定的IP和端口(根据你的Nginx配置,后端在8001端口)
|
|
||||||
bind = "127.0.0.1:8001"
|
bind = "127.0.0.1:8001"
|
||||||
|
|
||||||
# 工作进程数(根据CPU核心数调整,建议:CPU核心数*2+1)
|
# 必须用 gthread:sync 模式下 4 worker 同时只能处理 4 个请求,远程 MySQL 一慢就全站卡死
|
||||||
# 查看CPU核心数:cat /proc/cpuinfo | grep "processor" | wc -l
|
workers = 6
|
||||||
workers = 4
|
threads = 4
|
||||||
|
worker_class = "gthread"
|
||||||
|
|
||||||
# 工作模式(使用gevent支持异步,更高效)
|
timeout = 120
|
||||||
#worker_class = "gevent"
|
graceful_timeout = 30
|
||||||
worker_class = "sync" # 改成这个
|
|
||||||
|
|
||||||
# 每个worker的最大请求数(防止内存泄漏)
|
|
||||||
max_requests = 1000
|
|
||||||
max_requests_jitter = 50 # 随机抖动,避免所有worker同时重启
|
|
||||||
|
|
||||||
# 超时时间(秒)
|
|
||||||
timeout = 30
|
|
||||||
keepalive = 2
|
keepalive = 2
|
||||||
|
|
||||||
# 预加载应用(减少内存占用,加快请求处理)
|
max_requests = 2000
|
||||||
preload_app = True
|
max_requests_jitter = 100
|
||||||
|
|
||||||
# 日志配置
|
# 禁止输出到 stdout/stderr(曾灌满 journal 导致整机卡)
|
||||||
# 访问日志:输出到标准输出,便于OnePanel查看
|
accesslog = None
|
||||||
accesslog = "-"
|
errorlog = "/tmp/gunicorn-error.log"
|
||||||
# 错误日志:输出到标准错误
|
loglevel = "warning"
|
||||||
errorlog = "-"
|
|
||||||
# 日志级别
|
# gthread + MySQL 连接池:preload 易在 fork 后出连接问题
|
||||||
loglevel = "info"
|
preload_app = False
|
||||||
|
|
||||||
# 进程名称(便于识别)
|
|
||||||
proc_name = "a_long_dianjing_gunicorn"
|
proc_name = "a_long_dianjing_gunicorn"
|
||||||
|
|
||||||
# 工作进程的用户/组(安全考虑,用非root用户运行)
|
|
||||||
# user = "www-data"
|
|
||||||
# group = "www-data"
|
|
||||||
|
|
||||||
# 工作进程临时目录(避免权限问题)
|
|
||||||
worker_tmp_dir = "/dev/shm"
|
worker_tmp_dir = "/dev/shm"
|
||||||
|
daemon = False
|
||||||
|
|
||||||
# 限制请求数据大小(防止大文件攻击)
|
|
||||||
limit_request_line = 4094
|
limit_request_line = 4094
|
||||||
limit_request_fields = 100
|
limit_request_fields = 100
|
||||||
limit_request_field_size = 8190
|
limit_request_field_size = 8190
|
||||||
|
|
||||||
# 优雅退出时间
|
|
||||||
graceful_timeout = 30
|
|
||||||
|
|
||||||
# 进程守护(如果用systemd管理,这里设为False)
|
|
||||||
daemon = False
|
|
||||||
Reference in New Issue
Block a user