【问题标题】:How to achieve below objective.?如何实现以下目标。?
【发布时间】:2020-01-14 13:24:24
【问题描述】:

我在 Django 中使用 celery。 Redis 是我的经纪人。我通过 Apache 和 WSGI 为我的 Django 应用程序提供服务。我在主管模式下运行芹菜。我正在从我的 Django 项目的wsgi.py 文件中启动一个名为run_forevercelery task。我的意图是在 Django 启动时启动一个 celery 任务并在后台永远运行它(我不知道这是否是实现相同目标的正确方法。我搜索了它但找不到合适的实现。如果你有任何更好的想法,请分享)。它按预期工作。现在由于某些问题,我在apache的虚拟主机中添加了maximum-requests-250参数。通过这样做,当它收到 250 个请求时,它会重新启动 WSGI 进程。

因此,当它每次重新启动时,都会创建一个 celery 任务“run_forever”并在后台运行。最终,当服务器收到 1000 个请求时,WSGI 进程将重新启动 4 次,我最终拥有 4 个“run_forever”任务副本。我只想让任务的一份副本在任何时间点运行。所以我想在每次 Django 启动时杀死所有当前正在运行的“run_forever”任务。

我试过了

from project.celery import app
from project.tasks import run_forever
app.control.purge()
run_forever.delay()

在 wsgi.py 中,在启动 `run_forever' 之前终止所有正在运行的任务。但是没用

【问题讨论】:

  • 如果你不在标题中总结问题,你是不可能得到答案的。
  • 您想通过这种方法解决什么问题?

标签: django celery django-celery celery-task


【解决方案1】:

我必须同意 Dave Smith 的观点——为什么你有一个永远运行的任务?也就是说,如果您想防止任务运行两次,您可以使用多种策略。最简单的实现是使用数据库条目(因为数据库可以是事务性的,如果您使用 django,可能您至少使用了一个数据库)。注意,在下面的代码 sn-p 中,我没有将模型放在正确的位置以供迁移使用——我只是将它放在同一个 sn-p 中以便于讨论。

import time
from myapp.celery import app
from django.db import models

class CeleryGuard(models.Model):
    task_name = models.CharField(max_length=32)
    task_id = models.CharField(max_length=32)

@app.task(bind=True)
def run_forever(self):
    created, x = CeleryGuard.objects.get_or_create(
        task_name='run_forever', defaults={
            'task_id': self.request.id
        })
    if not created:
        return
    # do whatever you want to here
    while True:
        print('I am doing nothing')
        time.sleep(1440)
    # make sure to cleanup after you are done
    CeleryGuard.objects.filter(task_name='run_forever').delete()

【讨论】:

  • 为什么你有一个永远运行的任务?答:我正在使用 MQTT。 Django 应用程序是一个 mqtt 客户端,它侦听代理以获取来自 IOT 客户端的传入消息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多