定期任务:Periodic Tasks
celery beat
是一个调度程序;它定期启动任务,然后由集群中的可用节点执行任务。默认情况下会从配置中的
beat_schedule
项中获取条目(entries),但是也可以使用自定义存储,例如将entries存储在SQL数据库中。应确保一次只运行一个调度程序来执行一个调度程序,否则最终将导致重复的任务。使用集中式方法意味着时间表不必同步,并且该服务可以在不使用锁的情况下运行。
默认情况下,定期任务计划使用UTC时区,但是可以使用时区设置更改使用的时区。 例如配置 Asia/Shanghai:
timezone = 'Asia/Shanghai'
必须通过直接使用(
app.conf.timezone ='Asia/Shanghai'
)对其进行配置,或者如果已使用app.config_from_object
对其进行了设置,则可以将该设置添加到您的应用程序模块(既常用的celeryconfig.py
)中。有关配置选项的更多信息,请参见配置。默认的调度程序(将调度程序存储在
celerybeat-schedule
文件中)将自动检测到时区已更改,并重置调度程序本身,但是其他调度程序可能不那么聪明(例如Django数据库调度程序,请参见下文,在这种情况下,您必须手动重置调度计划。对于django用户 Celery建议并与Django 1.4中引入的新
USE_TZ
设置兼容。 对于Django用户,将使用TIME_ZONE
设置中指定的时区,或者可以使用celery的timezone
设置单独为Celery指定自定义时区。 更改与时区相关的设置时,数据库调度程序不会重置,因此您必须手动执行以下操作:$ python manage.py shell
>>> from djcelery.models import PeriodicTask
>>> PeriodicTask.objects.update(last_run_at=None)
Django-Celery仅支持Celery 4.0及更低版本,对于Celery 4.0及更高版本,请执行以下操作:
$ python manage.py shell
>>> from django_celery_beat.models import PeriodicTask
>>> PeriodicTask.objects.update(last_run_at=None)
要定期调用任务,您必须在周期调 度列表中添加一个条目(entry)。
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
# Calls test('world') every 30 seconds
sender.add_periodic_task(30.0, test.s('world'), expires=10)
# Executes every Monday morning at 7:30 a.m.
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1),
test.s('Happy Mondays!'),
)
@app.task
def test(arg):
print(arg)
从
on_after_configure
处理程序中进行设置意味着我们在使用test.s()
时不会在模块级别评估应用程序。请注意,on_after_configure
是在设置应用程序后发送的,因此在声明应用程序的模块之外的任务(例如,在celery.Celery.autodiscover_tasks()
位于的task.py文件中)必须使用稍后的信号,例如on_after_finalize
。 add_periodic_task()
函数会将条目添加到幕后的beat_schedule
设置中,并且该设置也可以用于手动设置周期性任务: 例如 每30秒运行task.add任务。app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'
注意 如果想知道这些设置应该去哪里,请参阅配置。您可以直接在应用程序上(
app.conf.xxx
)设置这些选项,也可以保留单独的模块(celeryconfig.py
)进行配置。 如果您想对args使用单个项目元组,请不要忘记构造函数是逗号,而不是一对括号。与
cron
一样,如果第一个任务在下一个任务之前没有完成,则这些任务可 能会重叠。如果对此感到担忧,则应该使用锁定策略来确保一次只能运行一个实例(例如,请确保确保一次只能执行一个任务 one at one time)。task 要执行的任务的名称。
默认情况下,relative为false,频率不四舍五入,将与开始
celery beat
的时间有关。如果要对执行任务的时间(例如,一天中的特定时间或一周中的某天)进行更多控制,则可以使用crontab调取类型:
from celery.schedules import crontab
app.conf.beat_schedule = {
# Executes every Monday morning at 7:30 a.m.
'add-every-monday-morning': {
'task': 'tasks.add',
'schedule': crontab(hour=7, minute=30, day_of_week=1),
'args': (16, 16),
},
}
这些Crontab表达式的语法非常灵活 一些例子
Example | Meaning |
crontab() | Execute every minute. |
crontab(minute=0, hour=0) | Execute daily at midnight. |
以下略
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), # 圣保罗教堂日落 cool~
'args': (16, 16),
},
}
参数很简单:solar(事件,纬度,经度) 确保对纬度和经度使用正确的符号:
sign | Argument | Meaning |
+ | latitude | North |
+ | latitude | South |
+ | longitude | East |
+ | longitude | West |
所有太阳事件都是使用UTC计算的,因此不受时区设置的影响。 在极地地区,太阳不一定每天都会升起或落下。调度程序可以处理这些情况(例如,在太阳不升起的一天不会发生日出事件)。一个例外是
solar_noon
,正式定义为太阳经过天体子午线的那一刻,即使太阳在地平线以下,它也会每天发生。暮光定义为黎明到日出之间的时间;在日落和黄昏之间。您可以使用上面列表中的适当事件,根据您对暮光的定义(民用,航海或天文学的)以及是否要在暮光的开始或结束时,根据“暮光”安排事件。 。
启动
celery beat
服务$ celery -A proj beat
您还可以通过启用
workers -B
选项将celert beat
嵌入到worker内,如果您永远不会运行一个以上的worker节点,这很方便,但是它并不常用,因此不建议用于生产环境:$ celery -A proj worker -B
Beat需要将任务的最后运行时间存储在本地数据库文件(默认情况下命名为
celerybeat-schedule
)中,因此需要访问该文件才能在当前目录中进行写操作,或者您可以为此文件指定一个自定义位置:$ celery -A proj beat -s /home/celery/var/run/celerybeat-schedule
还有django-celery-beat扩展程序,用于将调度存储在Django数据库中,并提供了一个方便的管理界面来在运行时管理定期任务。
要安装和使用此扩展: 使用pip安装软件包:
$ pip install django-celery-beat
将django_celery_beat模块添加到Django项目的settings.py中的INSTALLED_APPS中:
INSTALLED_APPS = (
...,
'django_celery_beat',
)
请注意,模块名称中没有短划线,只有下划线。 应用Django数据库迁移,以便创建必要的表:
$ python manage.py migrate
使用
django_celery_beat.schedulers:DatabaseScheduler
调度程序启动celery beat
服务:$ celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
请使用Django-Admin界面设置一些定期任务。
Last modified 2yr ago