Python 芹菜为什么不节拍';t安排定期任务?

Python 芹菜为什么不节拍';t安排定期任务?,python,celery,celerybeat,Python,Celery,Celerybeat,我已经按照芹菜文档创建了一个应用程序和定期任务,如下所示: $ 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

我已经按照芹菜文档创建了一个应用程序和定期任务,如下所示:

$ 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...
$ 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!")

然后按如下方式运行芹菜节拍:

$ 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...
$ 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!")

请稍候,没有安排任何任务

但是,如果我在config中更改为set
CELERYBEAT\u SCHEDULE
,它可以很好地工作。为此,我将
demo/config.py
demo/tasks.py
更改如下:

$ 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...
$ 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!")

然后使用与之前相同的命令运行芹菜节拍,周期性任务可以按预期每3秒安排一次


我以前的设置有什么问题?

您必须根据
--scheduler
键指定计划程序。例如,您可以尝试以下代码:

celery beat -A demo -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

另外,我不确定
--max interval
是否会影响您的日程安排。我认为最好删除此选项。IMHO.

芹菜4.x不使用大写配置变量-请参阅芹菜文档的一节。将列出特定于计划程序的配置参数。因此,尝试修改代码,使其具有
beat_schedule={
而不是
CELERYBEAT_schedule={
。您所说的链接也使用小写名称…

仅供参考,我想出了另一个解决方案,在配置后更改装饰程序
@app.on.\u。将
连接到
@app.on.\u finalize.connect
可以让它工作。尽管我现在不知道确切原因。

默认的调度程序是“celery.beat.PersistentScheduler”正如您在celery beat命令的输出中所看到的。大写配置变量也可以工作,因为celery 4.x也支持旧格式配置,在我的示例中,“CELERYBEAT_SCHEDULE”工作得很好。不起作用的是原始版本的代码,它在_configure.connect“+”setup_任务之后使用“@app.on_”“。我自己也遇到过这种情况。这是因为,
芹菜.py
末尾发送了\u configure
之后,
上的
,但是
任务.py
模块直到很久以后才加载(
自动发现任务()
不会立即执行,因为Django必须完成应用程序的设置。)因此,在发送了配置后,在上用
on\u修饰的任何定期任务都不会被导入。请在此解释问题: