本文首发于公众号:Hunter后端
原文链接:celery笔记七之周期/定时工作及crontab定义
periodic task,即为周期,或者定时工作,比如说每天晚上零点零分须要运行一遍某个函数,或者每隔半小时运行一遍该函数,都是这种工作的领域。
在第一篇笔记的时候咱们就介绍过 celery 的组件形成,其中有一个组件叫做 beat,就是咱们定时工作的调度器。
所有的定时工作都由 beat 收回,这种状况下,你必须确保在同一个工夫点只有一个 beat 任务调度器在运行,假如有两个 beat 同时在运行,那么在检测定时工作的时候,零碎的工作就可能会被反复发动、调用、执行。
- beat_schedule 定义
- beat 启动
- crontab介绍
1、beat_schedule 定义
咱们来定义两个定时工作,一个是 blog.tasks.add,定义为每隔 30s 执行一次,当初早晨11点45分,咱们定义每天11点50分执行一次。
在进行这些操作前,咱们还须要对时区有一些设置,因为咱们设置的早晨11点是北京工夫,而 Django 和 celery 默认是格林威治工夫。
时区设置
咱们应用 Django 零碎,一些配置在 settigns.py 中定义,详情能够见前几篇笔记的 celery 与 Django 零碎应用。
对于时区,Django 零碎和 celery 的时区咱们都设置成北京工夫:
# settings.py# django 时区设置TIME_ZONE = "Asia/Shanghai"USE_TZ = False# celery 时区设置 CELERY_TIMEZONE = "Asia/Shanghai"CELERY_ENABLE_UTC = FalseDJANGO_CELERY_BEAT_TZ_AWARE = False
定时工作定义
接下来,咱们定义定时工作:
from celery.schedules import crontabapp.conf.beat_schedule = { 'add-every-30-seconds': { 'task': 'blog.tasks.add', 'schedule': 30, 'args': (16, 16), }, 'schedule_test_add': { 'task': 'blog.tasks.minus', 'schedule': crontab(minute="50", hour="23"), },}
定时工作的定义是咱们通过 app.conf.beat_schedule 来操作,一个工作咱们定义一个 name 作为 key
在每个 task 下,别离有以下选项:
task:指向咱们定义的工作,比方咱们这个是指向 blog application 下 tasks.add 工作
schedule:定时工作的策略,如果间接定义一个整数,比方定义的 add-every-30-seconds task 的这个参数定义为 30,就会每隔30s 执行一次
而如果应用 crontab() 函数,则能够更自在的定义到每个月,每周,每天,每时每秒,在示例中咱们定义 minute="50", hour="23" 示意每天 23点50分执行一次
更具体的策略咱们上面再具体介绍。
args:定时工作的参数,比方 add() 函数,咱们每隔 30s 执行一次,给定的两个参数是 (16, 16),对应 add(x, y) 输出的两个值
2、beat 启动
beat 的启动形式和 worker 启动形式统一,将 worker 改成 beat 即可:
celery -A hunter beat -l INFO
也能够指定日志的输入文件:
celery -A hunter beat -l INFO --logfile=/Users/hunter/python/celery_log/beat.log
当咱们启动 beat 的时候,会发现启动的文件夹下会有一个名为 celerybeat-schedule.db 的文件,这个是 beat 保留在本地的上一次工作运行的工夫的数据,咱们也能够指定该文件的输入地址:
celery -A hunter beat -l INFO -s /Users/hunter/python/celery_log/celerybeat-schedule
如果咱们须要运行定时工作,咱们须要额定启动两个服务,一个是 beat,一个是 worker
一般来说咱们会先启动 worker,再启动 beat,这样 beat 有一些立刻收回的工作就能够间接被 worker 接管而后运行。
3、crontab介绍
咱们应用 crontab() 函数制订定时工作的工夫策略,比方每天运行一次,或者指定周几运行都能够实现。
如果你之前接触过 Linux 服务器上的 crontab 服务,那么就不必放心了解它的应用形式,如果没有,咱们能够看看上面官网文档对着的介绍。
在 celery 里,crontab 函数通过 from celery.schedules import crontab 引入,在 beat_schedule 的定义里作为 schedule 的值,这个后面给过一个示例。
crontab 承受五个参数:
- minute 示意分钟,接管整数或者整数列表,范畴在0-59,或者字符串示意配置的工夫模式
- hour 示意小时,接管整数或者整数列表,范畴在0-23,或者接管字符串示意配置的工夫模式
- day_of_week 示意周几,接管整数或者整数列表,范畴在0-6,其中周日是0,周六是6,或者接管字符串示意配置的工夫模式
- day_of_month 示意一个月的第几天,接管整数或者整数列表,范畴在1-31,或者接管字符串示意配置的工夫模式
- month_of_year 示意一年的第几个月,接管整数或者整数列表,范畴在1-12,或者接管字符串示意配置的工夫模式
minute 和 hour
minute 和 hour 间接指向一天的某个工夫点,所以,这两个参数相当于是必填,除非是某些非凡的状况,比方默认的每分钟执行一次:
crontab()
下面的命令,什么参数也不传,示意的是每隔一分钟执行一次
如果咱们想指定特定的工夫点,比方每天晚上11点23分执行一次:
crontab(minute=23, hour=23)
如果咱们想指定某一些分钟,比方别离在 23点11分,23点25分,23点44分钟别离执行一次,能够如下操作:
crontab(minute="11,25,44", hour=23)
如果是下面这种没有非凡关系的工夫点,咱们能够这样通过逗号分隔连接起来,如果是有非凡关系的,比如说,每隔一分钟,或者每隔三分钟,咱们能够通过 */n
的形式来连贯。
23点之内,每隔三分钟执行一次函数能够如下操作:
crontab(minute="*/3", hour=23)
这里的每隔 n 分钟,其实是 n 的倍数,比如说 */3
就是在 0,3,6,9,12... 等这些分钟数上执行。
还有一种是范畴内的操作形式,比如说,23点的 10-20分钟内每分钟执行一次:
crontab(minute="10-20", hour=23)
那么下面的形式合并起来可不可以,比如说在23点的第5分钟,11分钟,51分钟,31-40分钟,并且每隔两分钟执行一次
也能够实现,把下面的形式都增加在一起,就是一个或的操作:
crontab(minute="5,11,51,10-20,*/2", hour=23)
对于分钟的这些操作,对于小时数是同样失效的,不过范畴在 0-23 之间,比如说指定0点,5点,8点,16点的零分执行一次,那就是:
crontab(minute=0, hour="0,5,8,16")
如果是每个小时执行一次呢,就是:
crontab(minute=0, hour="*/1")# 当 n = 1 的时候 1能够省略,即为crontab(minute=0, hour="*")
hour 的范畴参数和指定的小时点,像 minute 参数一样,也是能够或操作性能那样失效的。
day_of_week
day_of_week 参数示意周几,当咱们应用这个参数的时候,minute 和 hour 参数是同样失效的,这里咱们只演示 day_of_week 参数的作用,小时和分钟咱们都定为 0点0分。
当咱们不指定这个参数的时候,即为每天,只有指定了这个参数的时候,定义的周几才会失效,比方咱们定义在周一,周三,周五三天的零点执行一次:
crontab(minute=0, hour=0, day_of_week="1,3,5")
这里,周日是0,周一是1,周二是2,顺次类推。
day_of_week 的参数还能够应用英文的简写,这里不做介绍,因为我集体认为还是间接应用数字不便一点。
另一个须要留神的是,day_of_week 也能够应用 */n
的模式,然而周几总共只有7个,所以我这里举荐间接用数字写进去。
day_of_month
示意一个月的第几天,范畴是1-31。
其应用办法和 minute、hour 应用的形式是统一的,应用范畴和 */n
的模式都能够实现。
比方咱们想实现在1号,5号,7号,8号,以及每个偶数日的零点零分执行一次,能够这样操作:
crontab(minute=0, hour=0, day_of_month="1,5,7,8,*/2")
month_of_year
示意一年的某几个月,范畴是1-12。
和后面的应用形式统一,如果须要应用,只有12个数字,还是举荐间接定义。
如果想获取更多后端相干文章,可扫码关注浏览: