配置Django中Celery的定时任务
settings.py中代码如下
from datetime import timedelta
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
# 'add-every-xx-seconds': {
# 'task': 'app_blog.blog.tasks.print_info',
# 'schedule': timedelta(seconds=2), # 每 30 秒一次
# # 'schedule': timedelta(minutes=1), # 每 1 分钟一次
# # 'schedule': timedelta(hours=4), # 每 4 小时一次
# 'args': ('settings中的定时任务',) # 任务函数参数,如果只有一个参数,一定要加逗号
# },
'send_qq_blog_request_count': {
'task': 'app_blog.blog.tasks.count_blog_everyday_request',
'schedule': crontab(hour=23, minute=30), # 每天晚上 23 点 30 分执行一次
}
}
-
timedelta
是datetime
中的一个对象,需要from datetime import timedelta
引入,有如下几个参数-
days
:天 -
seconds
:秒 -
microseconds
:微妙 -
milliseconds
:毫秒 -
minutes
:分 -
hours
:小时
-
Celery的crontab表达式
crontab是比较完善,可能有些复杂,但能实现各种设置时间的需求。
引入:from celery.schedules import crontab
crontab()
实例化的时候没设置任何参数,都是使用默认值。crontab一共有7个参数,常用有5个参数分别为:
-
month_of_year
:月份。范围1-12 -
day_of_month
:日期,范围1-31 -
day_of_week
:周几,范围0-6 -
hour
:小时,范围0-23 -
minute
:分钟,范围0-59
默认参数
这些参数可以设置表达式,表达稍微复杂的设置。默认值都是"*
"星号,代表任意时刻。即crontab()
相当与:
rontab(minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*')
含义是每天、每小时、每分钟执行一次任务。这说法太反人类语言习惯,简单说就是每1分钟执行一次任务。
具体某个值
直接设置某个值,每小时的15分时刻执行一次任务
crontab(minute=15)
直接指定某个时刻。上方设置每天0点0分时刻执行任务。
crontab(minute=0, hour=0)
也可以设置多个值。例如0分和30分执行一次任务
crontab(minute='0,30')
这里使用字符串,用逗号隔开数值。这里的逗号是表示多个表达式or逻辑关系。
设置范围
设置范围也是设置多个值,例如指定9点到12点每个小时的每分钟执行任务。
crontab(minute='*', hour='9-12')
这里*号是默认值,可以省略如下:
crontab(hour='9-12')
逗号是or逻辑关系,指定9点到12点和20点中每分钟执行任务:
crontab(hour='9-12,20')
crontab的表达式越来越复杂了。celery还提供了一个类得到表达式解析结果,代码如下:
from celery.task.schedules import crontab_parser
r = crontab_parser(23, 0).parse('9-12,20')
print(r)
# 结果:set([9, 10, 11, 12, 20])
其中,crontab_parse
是一个解析类。第1个参数是范围的最大值;第2个参数是范围的最小值。通过parse
输入表达式,可得到表达式的解析结果set([9, 10, 11, 12, 20])
。
设置间隔步长
设置1、3、5、7、9、11月份每天每分钟执行任务,按照上面的做法可以设置如下:
crontab(day_of_month='1,3,5,7,9,11')
观察数据可以发现,都是间隔2的步长。需要设置的数字比较少,若数字比较多显得很麻烦。例如我想每间隔2分钟就执行一次任务,要写30个数字想想就觉得很麻烦。crontab表达式还提供了间隔的处理,例如:
crontab(minute='*/2')
crontab(minute='0-59/2') #效果等同上面
这个/
号不是除以的意思。相当与range的第3个参数步长,例如:
range(0, 59+1, 2)
示例
# 每2个小时中每分钟执行1次任务
crontab(hour='*/2')
# 每3个小时的0分时刻执行1次任务
# 即[0,3,6,9,12,15,18,21]点0分
crontab(minute=0, hour='*/3')
# 每3个小时或8点到12点的0分时刻执行1次任务
# 即[0,3,6,9,12,15,18,21]+[8,9,10,11,12]点0分
crontab(minute=0, hour='*/3,8-12')
# 每个季度的第1个月中,每天每分钟执行1次任务
# 月份范围是1-12,每3个月为[1,4,7,10]
crontab(month_of_year='*/3')
# 每月偶数天数的0点0分时刻执行1次任务
crontab(minute=0, hour=0, day_of_month='2-31/2')
# 每年5月11号的0点0分时刻执行1次任务
crontab(0, 0, day_of_month='11', month_of_year='5')