Celery(四)定时任务
要定时或者周期性的执行任务,可以使用linux的crontab。Celery也提供了类似的Periodic Tasks功能。
Celery beat
Celery使用celery beat作为任务调度器,周期性的启动任务。
需要执行的任务默认是在beat_schedule配置选项中设置的。使用django-celery-beat时,也可以使用数据库存储。
需要保证同一时间只有一个任务调度器在运行,否则会重复的执行任务。
Time Zones
既然是任务与时间有关,那么时区设置是很重要的。Celery默认使用UTC时区,要改变默认时区,可以配置:
1 | timezone = Asia / Shanghai' |
在django项目中使用celery时,celery也可以使用setting的TIME_ZONE时区设置。
使用默认的任务调度器时,celery会自动识别时区的改动,然后重置任务调度。使用其它任务调度时,需要手动重置。
比如,使用django-celery-beat时:
1 2 3 | $ python manage.py shell >>> from djcelery.models import PeriodicTask >>> PeriodicTask.objects.update(last_run_at = None ) |
Entries
要添加周期任务,需要将事务添加到任务调度器中,添加方法有两种。
一种是使用add_periodic_task() 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from __future__ import absolute_import, unicode_literals from celery.schedules import crontab from .celery import app @app .on_after_configure.connect def setup_periodic_tasks(sender, * * kwargs): # Calls add(1, 2) every 10 seconds. sender.add_periodic_task( 10.0 , add.s( 1 , 2 ), name = 'add every 10' ) # Calls add(3, 4) every 30 seconds sender.add_periodic_task( 30.0 , add.s( 3 , 4 ), ) # Executes every Monday morning at 7:30 a.m. sender.add_periodic_task( ┆ crontab(hour = 7 , minute = 30 , day_of_week = 1 ), ┆ add.s( 1 , 2 ), ) @app .task def add(x, y): print x + y return x + y |
另一种方法是配置beat_schedule选项:
1 2 3 4 5 6 7 | app.conf.beat_schedule = { 'add-every-30-seconds' : { 'task' : 'tasks.add' , 'schedule' : 30.0 , 'args' : ( 3 , 4 ) }, } |
可用字段:
task:需要执行的任务名称
schedule:任务执行时间设定,可以是整秒数,一个timedelta对象,或者一个crontab对象,也可以自己实现。
args:一个元组或者列表,位置参数
kwargs:一个字典,关键字参数
options:一个字典,一些额外选项,apply_async()方法可用的参数,exchange, routing_key, expires等
relative:默认false
Crontab
class celery.schedules.crontab(minute=u'*', hour=u'*', day_of_week=u'*', day_of_month=u'*', month_of_year=u'*', **kwargs)
一个表示时间间隔的对象,语法与linux的crontab类似。
minute和hour可以设置为*/15,*/2,分别表示每隔15分钟和每隔2小时。
day_of_week用可以0-6的数字表示,也可以文字表示mon-fri。*/2并不是每2天,而是每半天。
官网一些具体例子:
crontab() 每分钟
crontab(minute=0, hour=0) 每天的0时0分
crontab(minute=0, hour='*/3') 每三小时
crontab(day_of_week='sunday') 周日的每一小时
crontab(minute='*',hour='*', day_of_week='sun') 与上面相同
crontab(minute=0, hour='*/3,8-17') 每三个小时 8时到17时的每小时
Solar
可用日升日落表示的时间间隔:
1 2 3 4 5 6 7 8 9 10 | from celery.schedules import solar app.conf.beat_schedule = { # Executes at sunset in Melbourne 'add-at-melbourne-sunset' : { 'task' : 'tasks.add' , 'schedule' : solar( 'sunset' , - 37.81753 , 144.96715 ), 'args' : ( 16 , 16 ), }, } |
语法是solar(event, latitude, longitude)
event表示日落日出,latitude为纬度,北纬为+,longitude为经度,东经为+。
启动
启动celery beat周期任务命令:
1 | $ celery - A proj beat |
然后启动worker节点来处理任务即可。
beat与worker也可以同时启动,但最好只用于测试,适用于只启动一个worker节点的情况:
1 | $ celery - A proj worker - B |
beat会在当前目录下建立一个文件celerybeat-schedule来记录任务上次运行的时间,所以要保证celery对当前目录有写入的权限,或者指定文件位置:
1 | $ celery - A proj beat - s / home / celery / var / run / celerybeat - schedule |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探