在DigitalOcean小内存Droplet部署Django应用时遇错误码247求助
错误码247分析与解决(Django+Postgres+Redis+Celery部署在512MB内存Droplet)
首先明确:错误码247是Linux系统OOM Killer(内存耗尽杀手)终止进程的标志——当机器内存完全耗尽时,系统会主动杀掉占用内存最多的进程来避免崩溃,你的Django容器进程就是被这么干掉的。结合你用的是512MB内存的低配Droplet,同时跑Django、Postgres、Redis、Celery四个服务,内存不足是核心问题,但也可以通过配置优化缓解。
一、先救急:临时扩容内存+限制容器资源
1. 添加Swap分区
给机器加1GB swap作为内存扩展,直接执行以下命令:
sudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 设置开机自动挂载swap echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
2. 给容器加内存限制
在你的docker-compose.yml里给每个服务添加内存上限,防止单个服务吃光所有内存,示例配置:
services: django: # 你的原有配置 deploy: resources: limits: memory: 150M postgres: # 你的原有配置 deploy: resources: limits: memory: 128M redis: # 你的原有配置 deploy: resources: limits: memory: 64M celery: # 你的原有配置 deploy: resources: limits: memory: 100M
二、深度优化各服务配置
Postgres优化(最吃内存的服务之一)
Postgres默认配置是给大内存机器用的,必须改:
- 如果是用docker镜像,挂载自定义
postgresql.conf文件,调整以下参数:
也可以通过环境变量传递部分参数,比如shared_buffers = 16MB # 512MB内存机器最多设到64MB,这里选16MB更保守 work_mem = 64KB # 降低单个连接的工作内存 maintenance_work_mem = 32MB effective_cache_size = 128MB max_connections = 20 # 减少最大连接数,避免多连接占内存POSTGRES_SHARED_BUFFERS=16MB。
Django优化
- 强制关闭
DEBUG=False(生产环境必须关,DEBUG模式会缓存大量调试信息,占内存) - 删除不必要的中间件,只保留
SecurityMiddleware、CommonMiddleware、CsrfViewMiddleware、AuthenticationMiddleware这类核心中间件 - 用
gunicorn替代默认的runserver,并且只开1个worker:gunicorn --workers=1 --threads=2 your_project.wsgi:application
Celery优化
- 只启动1个worker,在docker-compose的celery命令里加
--concurrency=1:celery: command: celery -A your_project worker --loglevel=info --concurrency=1 - 任务里尽量避免加载大对象,处理完及时释放内存
Redis优化
- 修改Redis配置,设置
maxmemory 32mb,并开启maxmemory-policy allkeys-lru,让Redis内存满时自动淘汰旧键值对
三、长期方案
如果以上优化后还是频繁出现OOM,建议直接升级Droplet到1GB内存的机型——512MB内存同时跑四个服务属于极限操作,只能应付极低流量的测试场景,生产环境肯定扛不住。
内容的提问来源于stack exchange,提问作者Matteo Possamai
相关产品推荐
相关产品推荐

