为何Heroku上的Docker化Django应用Celery任务无法启动?
问题排查与解决方案
1. 修复Celery实例冲突问题
你的代码里存在两个独立的Celery实例:celery.py中定义的app = Celery("mysite"),以及task.py里的app = Celery('transcribe'),这会导致任务无法被全局worker正确发现。
修改task.py,改用项目全局的Celery实例:
# task.py from celery import shared_task @shared_task def transcribe_file_task(path, audio_language, output_file_type, dest_dir, session_id): print(f"TASK: {session_id}") # rest of code return output_file
2. 优化Celery Worker内存占用
Heroku基础dyno默认内存配额为512MB,你的celery dyno占用已达788MB(超出154%),会被Heroku强制限制资源,直接导致任务无法启动或执行中断。
调整Worker进程数
默认Celery会根据CPU核心数创建worker进程,Heroku基础dyno仅1核,手动指定进程数为1可大幅降低内存占用:
修改heroku.yml中的celery启动命令:
run: celery: celery -A mysite worker --loglevel=info --concurrency=1
限制子进程内存上限
添加--max-memory-per-child参数,限制每个子进程的内存峰值,超出后自动重启进程:
run: celery: celery -A mysite worker --loglevel=info --concurrency=1 --max-memory-per-child=256000
(256000单位为KB,即限制单进程内存不超过256MB)
3. 开启Celery详细日志排查
当前日志未包含Celery任务执行的细节,调整启动命令提升日志级别:
run: celery: celery -A mysite worker --loglevel=debug --concurrency=1
然后通过命令heroku logs -d celery -t实时查看celery dyno的日志,确认任务是否被接收、是否存在执行报错。
4. 验证Redis队列状态
通过Heroku CLI进入Redis控制台,检查任务是否被正确发送到队列:
heroku redis:cli # 进入Redis后执行 LRANGE celery 0 -1
如果能看到任务数据,说明任务已成功发送到队列,问题出在worker端;如果队列中无任务,则需再次确认CELERY_BROKER_URL的环境变量配置是否生效。
内容的提问来源于stack exchange,提问作者tthheemmaannii
相关产品推荐
相关产品推荐

