Celery Beat多任务调度仅执行首个任务,其余任务未注册报错
问题描述
Celery Beat配置了多个定时任务,日志显示所有任务均被识别并调度,但仅notify_after_sobes任务正常执行,notify_send_sobes_link任务执行失败,报错:NotRegistered('celery_settings.tasks.notify_send_sobes_link')。
Beat日志示例:
[2023-12-07 14:56:00,042] celery.beat INFO Scheduler: Sending due task send_sobes_link (celery_settings.tasks.notify_send_sobes_link)
[2023-12-07 14:56:00,042] celery.beat INFO Scheduler: Sending due task after_sobes (celery_settings.tasks.notify_after_sobes)
Celery配置及任务定义:
app = Celery('tasks') app.config_from_object(celeryconfig) app.conf.timezone = 'Europe/Kiev' app.conf.enable_utc = False app.conf.beat_schedule = { 'notify_tomorrow_sobes_task': { 'task': 'celery_settings.tasks.notify_tomorrow_sobes', 'schedule': crontab(minute="00", hour="18"), }, 'send_sobes_link': { 'task': 'celery_settings.tasks.notify_send_sobes_link', 'schedule': crontab(minute="5"), }, 'after_sobes': { 'task': 'celery_settings.tasks.notify_after_sobes', 'schedule': crontab(minute="5"), }, } app.autodiscover_tasks() @app.task def notify_tomorrow_sobes(): asyncio.run(send_notify_tomorrow_sobes()) @app.task def notify_send_sobes_link(): asyncio.run(send_sobes_link()) @app.task def notify_after_sobes(): asyncio.run(after_sobes())
解决方案
1. 验证任务名称与Worker注册的一致性
NotRegistered错误核心是Celery Worker未注册该任务或任务名称不匹配。执行以下命令查看Worker已注册的任务列表:
celery -A celery_settings.tasks inspect registered
对比输出中的任务全名,修正beat_schedule中的task字段。例如如果Worker中注册的任务名是tasks.notify_send_sobes_link(因Celery实例名为'tasks'),则调整配置:
'send_sobes_link': { 'task': 'tasks.notify_send_sobes_link', 'schedule': crontab(minute="5"), },
2. 确保Worker能加载到任务模块
- 检查Worker启动命令是否指定了正确的模块路径:
celery -A celery_settings.tasks worker --loglevel=info
- 若使用
autodiscover_tasks(),需明确指定任务所在包,避免自动发现失败:
app.autodiscover_tasks(['celery_settings'])
3. 检查任务定义的作用域
确保@app.task装饰的任务绑定到当前Celery实例app,且代码在Worker启动时能被扫描加载,避免任务定义在未被Worker覆盖的文件中。
4. 清理Beat调度缓存(可选)
如果之前修改过任务名称,Beat可能缓存了旧信息,可删除默认调度文件后重启Beat:
rm celerybeat-schedule celery -A celery_settings.tasks beat --loglevel=info
内容的提问来源于stack exchange,提问作者solovey1

