搭配Nginx与Gunicorn启动时Celery Worker/Beat CPU占用过高问题排查
Celery启动CPU占用过高问题排查与优化建议
部署环境与启动方式
- app1:执行
sh run.sh,启动Celery Worker、Celery Beat、Nginx、Gunicorn - app2:执行
sh run-worker.sh,启动Celery Worker、Celery Beat
问题现象
将镜像部署到1vCPU、4核实例后,App1的Celery Worker与Celery Beat进程CPU占用率短期内接近100%,随后缓慢下降,需3-5分钟才能恢复到合理水平,Worker最终完成上线。
- 两个Worker间隔5分钟的日志显示:从初始化到就绪的时间跨度较长
- CPU监控截图显示:部署后CPU占用率瞬间冲高,随后逐步回落至正常区间
核心疑问
是否需要将Worker单独部署为第三个应用?还是存在可通过配置修复的问题?
相关配置脚本
app1 启动脚本 run.sh
#!/usr/bin/env bash set -o errexit set -o nounset python3 manage.py migrate --settings project.env.prod export DJANGO_SETTINGS_MODULE=project.env.prod celery -A project purge -f echo "Start celery worker 1" celery -A project worker --loglevel=INFO -P gevent --concurrency 24 -Q project_queue_1 -n worker1@project --detach echo "Start celery beat" celery -A project beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler --detach echo "Start nginx" service nginx start echo "Start gunicorn" gunicorn -b 0.0.0.0:8000 --timeout 0 -w 2 project.wsgi
app2 启动脚本 run-worker.sh
#!/usr/bin/env bash set -o errexit set -o nounset export DJANGO_SETTINGS_MODULE=project.env.prod echo 'Start celery worker 2' celery -A project worker --loglevel=INFO -P gevent --concurrency 24 -Q project_queue_2 -n worker2@project
celery.py 钩子配置
@celeryd_after_setup.connect def setup_direct_queue(sender, instance, **kwargs): logger.info("setup_direct_queue", worker=sender) @celeryd_init.connect(sender=None) def configure_worker(conf=None, **kwargs): logger.info("celeryd_init") @worker_process_init.connect(sender=None) def worker_process_init(sender=None, **kwargs): logger.info("worker_process_init", worker=sender) @worker_init.connect(sender=None) def worker_init(sender=None, **kwargs): logger.info("worker_init", worker=sender) @worker_ready.connect(sender=None) def worker_ready(sender=None, **kwargs): logger.info("worker_ready", worker=sender)
问题分析与优化方案
核心原因
1vCPU实例算力有限,但每个Celery Worker设置了--concurrency 24的gevent协程池,同时还要运行migrate、Nginx、Gunicorn、Celery Beat等进程,启动阶段CPU资源被过度争抢,上下文切换开销暴增,导致初始化过程被拉长。
配置修复步骤
- 降低Celery并发数:
Gevent协程的并发数并非越高越好,1vCPU环境下建议将--concurrency调整为4-8。过高的并发数会让CPU在大量协程间频繁切换,反而降低整体效率。 - 优化启动流程:
将python3 manage.py migrate和celery -A project purge -f这类耗时操作放在最前面执行,完成后再启动Worker、Beat、Nginx和Gunicorn,避免多进程同时抢占CPU。 - 优化Beat调度器:
使用django_celery_beat.schedulers:DatabaseScheduler会在初始化阶段频繁查询数据库,如果数据库与应用同实例,会进一步加重CPU负载。可临时切换为默认调度器验证,或优化数据库索引减少查询耗时。
是否需要单独部署Worker?
如果调整上述配置后,CPU占用和启动时间恢复正常,无需单独部署第三个应用。但如果业务后续任务量增长,或需要更高的服务稳定性,将Worker单独部署是更规范的选择——实现Web服务与任务处理的资源隔离,避免互相影响。
内容的提问来源于stack exchange,提问作者Florent
相关产品推荐
相关产品推荐

