一、背景
有一天,突然发现线上系统上的任务没有执行,状态一直是未完成。
看了一下celery的beat日志,发现周期任务和定时任务都不执行了。
重启项目,发现django_celery_beat_periodictask
中,也只是执行前面几个周期或者定时任务,某个定时任务后面的所有任务都不执行了
本地debug启动celery beat进程,一直打印日志:
celery beat -l debug
Writing entries...
二、分析
- 根据日志,到
django_celery_beat_periodictask
表中,查看不执行的任务,发现了其中一个定时任务数据异常。 - 到celery代码中,打断点调试
通过打断点,进到is_due
方法中,最后发现了定时任务的问题。
1.原因分析
周期任务表django_celery_beat_periodictask
的enabled字段是1,代表任务可以执行,但是定时调度表django_celery_beat_clockedschedule
的enabled字段是0,代表任务不执行,这样会导致is_due
永远返回false值,beat不再往下执行周期和定时任务。
2.数据是怎么错的?
页面创建了定时任务,定时任务执行完成之后
再次在页面编辑这个定时任务,不改定时时间,就会导致出现这个问题
三、解决措施
在编辑定时任务时,校验定时时间,新的定时执行时间不能小于旧的定时时间。
最后,提供一条sql,用于排查错误定时任务
SELECT
p.name,
p.enabled periodic_enabled,
c.clocked_time,
c.enabled clocked_enabled
FROM
django_celery_beat_periodictask p,
django_celery_beat_clockedschedule c
WHERE
p.clocked_id = c.id;