我正在用芹菜和Django。Redis是我的经纪人。我正在通过Apache和WSGI提供我的Django应用程序。我正在主管模式下运行芹菜。我正在从我的 Django 项目的文件中启动一个名为run_forever
wsgi.py
celery task
。我的目的是在 Django 启动时启动一个芹菜任务,并在后台永久运行它(我不知道这是否是实现相同目标的正确方法。我搜索了它,但找不到合适的实现。如果您有更好的主意,请分享(。它正在按预期工作。现在由于某些问题,我在 apache 的虚拟主机中添加了maximum-requests-250
参数。通过这样做,当它收到 250 个请求时,它会重新启动 WSGI 进程。
因此,每次重新启动时,都会创建"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,大概你正在使用至少一个数据库(。 注意,在下面的代码片段中,我没有将我的模型放在正确的位置以供迁移选择——我只是将其放在同一个片段中以便于讨论。
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()