django-celery-beat特定PeriodicTask未触发的排查求助
时区不匹配:django-celery-beat依赖Django的时区配置,如果Celery Beat进程的时区与Django时区不一致(比如Django用
Asia/Shanghai,Beat默认用UTC),会导致任务调度时间计算错误,看起来像是任务没触发。可以启动Beat时通过--timezone参数指定和Django一致的时区,或者检查settings.py里的TIME_ZONE和USE_TZ配置。Celery Beat进程未加载最新任务:如果Beat进程是在创建该PeriodicTask之前启动的,需要重启Beat才能读取数据库中的新任务。另外要确认Beat启动时指定了正确的调度器:
celery -A your_project beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler,如果用了其他调度器,数据库中的任务不会被识别。任务名称匹配问题:即使确认了任务名称正确,也要检查
@app.task是否手动指定了name参数,PeriodicTask的task字段必须和这个名称完全一致(包括大小写、完整模块路径)。比如任务注册时用了@app.task(name='my_custom_task'),那PeriodicTask里必须填my_custom_task,不能用自动生成的app.tasks.my_task。Redis锁或连接异常:当使用Redis作为Celery的消息中间件时,django-celery-beat会用Redis做分布式锁。如果锁键(比如
celery-beat-lock)未正常释放,或者Redis连接不稳定,Beat会无法获取调度权限,导致任务被忽略。可以登录Redis执行DEL celery-beat-lock删除锁,然后重启Beat。任务间隔配置逻辑错误:比如IntervalSchedule的
period选了minutes但every设为0,或者CrontabSchedule的参数冲突(比如同时指定了day_of_month=1和day_of_week=2,没有重合的时间点),导致任务没有符合条件的触发时间。数据库事务未提交:如果是通过代码创建PeriodicTask,若创建逻辑在未提交的数据库事务中,Beat读取数据库时无法获取到这条任务记录。需要确保代码创建任务后事务已提交,或者手动提交事务。
Beat日志级别过低:虽然没有报错,但Beat可能输出了调度相关的调试信息却没被看到。将Beat的日志级别调到DEBUG(启动时用
-l debug),查看是否有“Sending due task”的日志,确认任务是否被Beat识别。自定义调度器或过滤逻辑干扰:如果项目中自定义了Celery Beat的调度器,或者通过信号、数据库查询集修改了PeriodicTask的可见性,可能导致Beat无法读取到该任务。检查是否有自定义调度器的配置,或者影响PeriodicTask查询的代码。
内容的提问来源于stack exchange,提问作者aroooo

