我在python应用程序中使用的celery.scheduler无法正常工作

时间:2019-07-10 16:37:44

标签: python redis cron celery

我在执行定期任务时遇到问题?当我运行代码celery worker -A任务--loglevel = debug时。看起来不错,但是它停止了,并且在终端中显示以下消息后不执行任何操作: [2019-07-10 22:29:21,149:DEBUG / MainProcess] basic.qos:prefetch_count-> 16

from celery import Celery
from celery.schedules import crontab
from datetime import date, timedelta
from config import *
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
import smtplib
import ssl
import os

app = Celery('main', broker='redis://localhost')
app.conf.timezone = 'Asia/Bishkek'


@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    sender.add_periodic_task(30.0, send_archives(), expires=10)

@app.task
def send_archives():

    yesterday = date.today() - timedelta(days=1)

    if len(os.listdir('archives')):
        msg = MIMEMultipart()
        msg['Subject'] = 'Archives for ' + yesterday.strftime('%d_%m_%Y')
        msg['From'] = EMAIL_HOST_USER
        msg['To'] = EMAIL_HOST_RECEIVER

        for filename in os.listdir('archives'):
            with open(os.path.join('archives', filename), 'rb') as attachment:
                part = MIMEBase('application', 'octet-stream')
                part.set_payload(attachment.read())
                encoders.encode_base64(part)
                part.add_header(
                    "Content-Disposition",
                    f"attachment; filename={filename}",
                )
                msg.attach(part)
            os.unlink(os.path.join('archives', filename))

        context = ssl.create_default_context()
        with smtplib.SMTP_SSL(EMAIL_HOST, EMAIL_PORT, context=context) as server:
            server.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
            server.sendmail(EMAIL_HOST_USER, EMAIL_HOST_RECEIVER, msg.as_string())

1 个答案:

答案 0 :(得分:1)

问题出在expires=10中。容易误解此参数。它的作用是告诉Celery“如果您不能在10秒内执行此任务,则根本不要运行它”(任务“到期”)。

因此,每30秒将任务发送到Celery群集。如果任务运行时间超过30秒,您的队列将满,并且安排在此之后的许多任务将简单地过期。

更糟糕的是-如果您的任务由于某种原因而永远处于阻塞状态,那么这些任务会填满队列,并且其他任务将不会运行。