为什么 celery beat 不安排周期性任务?
Why celery beat doesn't schedule periodic tasks?
我已经按照 celery 文档 https://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html 创建了一个应用程序和定期任务,如下所示:
$ tree demo/
demo/
├── config.py
├── __init__.py
└── tasks.py
$ cat demo/__init__.py
# -*- coding: utf-8 -*-
from celery import Celery
app = Celery('demo')
app.config_from_object('demo.config')
$ cat demo/config.py
# -*- coding: utf-8 -*-
BROKER_URL = "redis://127.0.0.1:6379"
CELERY_TIMEZONE='UTC'
CELERY_IMPORTS = [
"demo.tasks",
]
$ cat demo/tasks.py
from demo import app
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(3.0, say.s(), name='say hello every 3s')
@app.task
def say():
print("Hello!")
然后运行芹菜拍打如下:
$ celery beat -A demo -l info --max-interval 10
celery beat v4.3.0 (rhubarb) is starting.
__ - ... __ - _
LocalTime -> 2019-12-12 16:26:41
Configuration ->
. broker -> redis://127.0.0.1:6379//
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]@%INFO
. maxinterval -> 10.00 seconds (10.0s)
[2019-12-12 16:26:41,234: INFO/MainProcess] beat: Starting...
请稍等,没有任务安排。
然而,如果我在配置中更改为设置 CELERYBEAT_SCHEDULE
,它可以很好地工作。我通过如下更改 demo/config.py
和 demo/tasks.py
来做到这一点:
$ cat demo/config.py
# -*- coding: utf-8 -*-
from datetime import timedelta
BROKER_URL = "redis://127.0.0.1:6379"
CELERY_TIMEZONE='UTC'
CELERY_IMPORTS = [
"demo.tasks",
]
CELERYBEAT_SCHEDULE = {
'say hello every 10 seconds': {
'task': 'demo.tasks.say',
'schedule': timedelta(seconds=3),
},
}
$ cat demo/tasks.py
from demo import app
@app.task
def say():
print("Hello!")
然后运行celery beat用和之前一样的命令,周期任务可以按预期每3秒调度一次。
我之前的设置有什么问题?
您必须根据 this userguide 通过 --scheduler
键指定调度程序。例如,您可以尝试如下代码:
celery beat -A demo -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
P.S。我不确定 --max-interval
不会干扰您的日程安排。认为最好删除此选项。恕我直言。
Celery 4.x 不使用大写的配置变量 - 请参阅 New lowercase settings section of the Celery documentation. Scheduler-specific configuration arguments are listed here。因此,请尝试修改您的代码以使用 beat_schedule = {
而不是 CELERYBEAT_SCHEDULE = {
。你说你关注的link也用小写的名字...
仅供参考,我想出了另一个解决方案,将装饰器 @app.on_after_configure.connect
更改为 @app.on_after_finalize.connect
可以使其工作。虽然暂时不知道具体原因
我已经按照 celery 文档 https://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html 创建了一个应用程序和定期任务,如下所示:
$ tree demo/
demo/
├── config.py
├── __init__.py
└── tasks.py
$ cat demo/__init__.py
# -*- coding: utf-8 -*-
from celery import Celery
app = Celery('demo')
app.config_from_object('demo.config')
$ cat demo/config.py
# -*- coding: utf-8 -*-
BROKER_URL = "redis://127.0.0.1:6379"
CELERY_TIMEZONE='UTC'
CELERY_IMPORTS = [
"demo.tasks",
]
$ cat demo/tasks.py
from demo import app
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(3.0, say.s(), name='say hello every 3s')
@app.task
def say():
print("Hello!")
然后运行芹菜拍打如下:
$ celery beat -A demo -l info --max-interval 10
celery beat v4.3.0 (rhubarb) is starting.
__ - ... __ - _
LocalTime -> 2019-12-12 16:26:41
Configuration ->
. broker -> redis://127.0.0.1:6379//
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]@%INFO
. maxinterval -> 10.00 seconds (10.0s)
[2019-12-12 16:26:41,234: INFO/MainProcess] beat: Starting...
请稍等,没有任务安排。
然而,如果我在配置中更改为设置 CELERYBEAT_SCHEDULE
,它可以很好地工作。我通过如下更改 demo/config.py
和 demo/tasks.py
来做到这一点:
$ cat demo/config.py
# -*- coding: utf-8 -*-
from datetime import timedelta
BROKER_URL = "redis://127.0.0.1:6379"
CELERY_TIMEZONE='UTC'
CELERY_IMPORTS = [
"demo.tasks",
]
CELERYBEAT_SCHEDULE = {
'say hello every 10 seconds': {
'task': 'demo.tasks.say',
'schedule': timedelta(seconds=3),
},
}
$ cat demo/tasks.py
from demo import app
@app.task
def say():
print("Hello!")
然后运行celery beat用和之前一样的命令,周期任务可以按预期每3秒调度一次。
我之前的设置有什么问题?
您必须根据 this userguide 通过 --scheduler
键指定调度程序。例如,您可以尝试如下代码:
celery beat -A demo -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
P.S。我不确定 --max-interval
不会干扰您的日程安排。认为最好删除此选项。恕我直言。
Celery 4.x 不使用大写的配置变量 - 请参阅 New lowercase settings section of the Celery documentation. Scheduler-specific configuration arguments are listed here。因此,请尝试修改您的代码以使用 beat_schedule = {
而不是 CELERYBEAT_SCHEDULE = {
。你说你关注的link也用小写的名字...
仅供参考,我想出了另一个解决方案,将装饰器 @app.on_after_configure.connect
更改为 @app.on_after_finalize.connect
可以使其工作。虽然暂时不知道具体原因