Celery 注册了任务,但 beat 没有从已安装的应用程序中安排任务

Posted

技术标签:

【中文标题】Celery 注册了任务,但 beat 没有从已安装的应用程序中安排任务【英文标题】:Celery registers task but beat is not scheduling tasks from installed apps 【发布时间】:2020-03-08 19:49:04 【问题描述】:

我在让 Celery/Celery Beat 安排除我的 celery.py 文件中的任务之外的任何任务时遇到问题。我可以看到任务注册“芹菜检查注册”,但任务没有按计划运行。我已经阅读了所有文档,但我正在碰壁。使用 Ubuntu WSL 在 Windows 上运行 Redis。

测试 - 每 10 秒运行一次并显示在我的 shell 中 PayClosedLines - 已注册,但在我运行 celery worker 时不会出现在我的 shell 中。

/proj/proj/celery.py

from __future__ import absolute_import
import os
from celery import Celery
from django.apps import apps


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
app = Celery('mysite')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: [n.name for n in apps.get_app_configs()])


@app.task(bind=True)
def debug_task(self):
    print('Request: [0!r'.format(self.request))


@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    sender.add_periodic_task(10.0, test.s('test'), name='add every 10')
    sender.add_periodic_task(10.0, )
    sender.add_periodic_task(30.0, test.s(), expires=10)


@app.task
def test(arg):
    print(arg)


'''
proj/proj/settings.py
BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'


from datetime import timedelta

CELERY_BEAT_SCHEDULE = 
    'Payout bets every 10 seconds': 
        'task': 'UFCBetting.tasks.PayClosedLines',
        'schedule': timedelta(seconds=10.0),
    ,

CELERY_IMPORTS = ('UFCBetting.tasks',)

proj/app/task.py

from __future__ import absolute_import, unicode_literals
from .MyBookieTools import get_odds
from .models import BettingLines, Bets, CustomUser

from celery import task, shared_task


@task(name='UpdateLinesTable')
def UpdateLinesTable():
    odds = get_odds()
    for odd in odds:
        bl = BettingLines()
        bl.fighter = odd[0]
        bl.line = odd[1]
        bl.save()


@shared_task
def PayClosedLines():
    unpaid_lines = BettingLines.objects.filter(result="W").exclude(payment_status=True)
    print(unpaid_lines)
    for line in unpaid_lines:
        print(line)
        if line.result == "W":
            unpaid_bets = Bets.objects.filter(line_id=line.id)
            print(unpaid_bets)
            for bet in unpaid_bets:
                user = CustomUser.objects.get(id=bet.placed_by_id)
                user.balance = user.balance + line.payout(amount=bet.bet_amount)
                user.save()
        line.payment_status = 1
        line.save()
    print("Closed lines paid.")

【问题讨论】:

【参考方案1】:

您的设置没有CELERY_BEAT_SCHEDULER 常量。

如果将此添加到设置中,则无需使用--scheduler 选项

CELERY_BEAT_SCHEDULER = `django_celery_beat.schedulers:DatabaseScheduler`

【讨论】:

【参考方案2】:

蟋蟀...这就是问题所在。我已经安装了 django-celery-beat,所以我需要像这样启动我的 beat worker。太菜鸟了,不知道为什么,但这有效。

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

而不是通常的

celery -A mysite beat

【讨论】:

以上是关于Celery 注册了任务,但 beat 没有从已安装的应用程序中安排任务的主要内容,如果未能解决你的问题,请参考以下文章

如何将基于类的任务传递给 CELERY_BEAT_SCHEDULE

基础入门_Python-模块和包.深入Celery之Beat触发定时/周期性任务?

Celery Beat:一次限制为单个任务实例

django-celery-beat 垃圾邮件到期任务

django redis celery 和 celery beats 的正确设置

使用 Flask 动态调度 Celery Beat 任务