Django应用运行致Nginx崩溃、服务器无法连接故障如何修复
故障根因
核心是uWSGI配置不合理+Django应用存在内存泄漏,触发系统OOM(内存耗尽)机制,最终导致整机无响应,故障逻辑完全匹配描述的现象:
- 初期内存占用持续升高,uWSGI工作进程先被OOM杀死,Nginx转发找不到后端服务,先返回
502 Bad Gateway - 内存占满后系统无法给sshd、网络协议栈等核心进程分配运行内存,随即出现域名ping不通、SSH连不上、所有Nginx托管服务全挂的情况
- 不启动Django时服务长期稳定,可直接排除Nginx、系统底层的故障点。
修复方案
按优先级从高到低操作:
1. 先修正uWSGI配置(90%的同类问题都是这个配置错了)
网上很多老教程要求uWSGI工作进程数配成CPU核数*2,这套配置只适用于大内存物理机,Amazon Lightsail入门款1G/2G内存的实例照抄必炸。
打开你的uWSGI应用配置文件(通常路径为/etc/uwsgi/sites/你的应用标识.ini),调整为以下适配小内存实例的参数:
# 1G内存实例配2个进程,2G内存最多配4个,绝对不要开多 processes = 2 # 每个进程配2个线程足够覆盖普通站点的并发需求 threads = 2 # 开启进程自动回收:每个进程累计处理5000个请求后自动重启,强制回收内存,专治代码侧的慢性内存泄漏 max-requests = 5000 # 进程回收的随机偏移量,避免所有进程同时重启打断服务 max-requests-delta = 300 # 单进程内存硬限制:单进程虚拟内存超过512M就强制重启,防止单个进程吃完全部内存 limit-as = 512 # 关闭所有没用到的uWSGI插件、功能(比如内置缓存、统计上报等),减少额外内存占用
改完执行systemctl restart uwsgi生效。
2. 调整OOM杀死优先级,避免核心进程先挂
默认OOM机制杀进程是按内存占用评分选,很容易先把sshd、Nginx主进程杀了导致彻底失联,手动调整优先级让内存不够时先杀uWSGI进程:
- 临时生效(重启后失效)执行以下命令:
# sshd服务设为最高保护等级,永远不被OOM杀死 echo "-1000" > /proc/$(pidof sshd)/oom_score_adj # Nginx主进程设为高保护等级 echo "-500" > /proc/$(cat /run/nginx.pid)/oom_score_adj # uWSGI进程设为最高优先级被杀死,内存不够先清它 echo "1000" > /proc/$(pidof uwsgi)/oom_score_adj
- 永久生效的话,分别编辑sshd、nginx、uwsgi对应的systemd服务文件,在
[Service]段落下加对应参数:- sshd服务加
OOMScoreAdjust=-1000 - Nginx服务加
OOMScoreAdjust=-500 - uWSGI服务加
OOMScoreAdjust=1000
改完执行systemctl daemon-reload && systemctl restart 对应服务名生效。
- sshd服务加
3. 排查Django代码侧的内存泄漏点
如果改完uWSGI配置后内存还是持续缓慢上涨,就是代码存在内存泄漏,重点排查几个高频坑:
- 必须把
settings.py里的DEBUG配置设为False,DEBUG模式会缓存所有请求的SQL语句、上下文对象,跑几小时就能占满几个G内存 - 不要在全局作用域、类静态属性里存大对象,比如全表查出来的QuerySet、大体积文件句柄、未释放的数据库连接,这类对象不会随请求结束被垃圾回收,越积越多直接爆内存
- 不要用本地内存缓存存大体积、无过期时间的对象,有缓存需求换成Redis服务,给所有缓存 key 设合理的过期时间
- 可以用
memory-profiler工具逐接口压测,定位到请求结束后内存不回落的问题代码段修复。
4. 加系统级内存兜底,防止彻底失联
- 开启2G大小的swap分区,内存紧张时用磁盘临时缓冲,避免直接触发OOM:
# Amazon Linux/Debian/Ubuntu通用操作 fallocate -l 2G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab # 调整swap触发阈值,内存占用到80%再用swap,避免过早用磁盘拖慢服务 sysctl vm.swappiness=20 echo "vm.swappiness=20" >> /etc/sysctl.conf
- 安装
earlyoom服务,内存占用到90%时自动提前杀死占内存最高的非核心进程,不会等系统完全卡死连不上SSH:
# Debian/Ubuntu执行 apt update && apt install earlyoom -y # Amazon Linux/CentOS执行 # yum install earlyoom -y systemctl enable --now earlyoom
验证标准
所有配置改完重启服务,持续观察24小时,用free -h、top命令监控内存占用,如果内存稳定在固定区间不持续线性上涨,就不会再出现之前的502、整机失联问题。
内容的提问来源于stack exchange,提问作者iMath
相关产品推荐
相关产品推荐

