Docker部署Django+Celery高CPU占用问题及稳定运行优化需求
解决方案:重任务场景下保障Django服务稳定运行
一、彻底隔离Celery任务与Django服务
- 严格限制Django仅负责任务提交,所有Playwright相关逻辑(如Chromium初始化、页面采集)必须移至Celery Worker侧执行,杜绝任务提交阶段的资源预加载操作。
- 配置Redis消息队列的连接池限制,避免Django侧创建过多连接占用资源:
# Django settings.py CELERY_BROKER_POOL_LIMIT = 5
二、Django服务性能与资源优化
- Fargate部署时,初始配置建议2vCPU+4GB内存,同时开启基于CPU使用率/请求数的自动扩缩容,避免单容器过载。
- 启用Redis缓存优化高频操作:配置
cached_session存储会话、cached_template_loader缓存模板片段,减少数据库查询与模板渲染开销。 - 生产环境强制关闭DEBUG模式,移除调试类中间件(如
DebugToolbarMiddleware),减少不必要的资源消耗。 - 使用Gunicorn作为WSGI服务器,合理配置worker数与连接参数:
(worker数建议设置为gunicorn myproject.wsgi:application --workers 5 --timeout 30 --keep-alive 52*CPU核心数 +1)
三、Celery Worker精细化管控
- EC2自动扩缩容策略基于队列任务数而非CPU使用率(Playwright任务高CPU属于正常场景),例如:队列任务数>50时新增实例,<10时缩减实例。
- 每个Celery Worker进程仅处理1个任务(
--concurrency=1),并给每个Worker容器/EC2实例绑定1vCPU配额,避免进程间CPU争抢。 - 给任务设置超时限制,防止资源长期占用:
from celery import shared_task @shared_task(soft_time_limit=300, time_limit=360) def scrape_website_task(url): # Playwright采集逻辑 - 启用Worker进程自动重启机制,避免内存泄漏:
celery -A myproject worker --concurrency=1 --max-tasks-per-child=10
四、Playwright任务自身优化
- 启用无头模式并禁用非必要功能,降低资源消耗:
from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch( headless=True, args=["--disable-images", "--disable-javascript"] # 根据采集需求调整 ) # 采集逻辑 - Worker初始化时创建全局浏览器实例,任务中复用上下文而非重复启动浏览器:
# Worker进程初始化时执行 browser = None def init_browser(): global browser from playwright.sync_api import sync_playwright p = sync_playwright().start() browser = p.chromium.launch(headless=True) # 任务中复用上下文 @shared_task def scrape_task(url): context = browser.new_context() page = context.new_page() page.goto(url) # 采集操作 context.close()
五、监控与告警
- 配置CloudWatch监控Django容器的CPU/内存/请求延迟、Celery队列长度/Worker状态,设置告警规则:当Django CPU使用率>70%持续5分钟,或队列任务数>100时触发告警。
- 预发布环境用
django-debug-toolbar排查慢查询与视图瓶颈,针对性优化数据库查询(如添加索引、使用select_related/prefetch_related减少JOIN次数)。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

