繁体   English   中英

Django Celery-使用RabbitMQ在视图之间以及任务之间传递对象

[英]Django Celery - Passing an object to the views and between tasks using RabbitMQ

这是我第一次使用Celery,说实话,我不确定我做对了。 我的系统必须在Windows上运行,因此我使用RabbitMQ作为代理。

作为概念证明,我试图创建一个对象,其中一个任务设置该值,另一个任务读取该值,并且我还想在转到某个URL时显示该对象的当前值。 但是我在所有对象之间共享对象时遇到问题。

这是我的celery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE','cesGroundStation.settings')

app = Celery('cesGroundStation')

app.config_from_object('django.conf:settings')

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

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

我要分享的对象是:

class SchedulerQ():

    item = 0

    def setItem(self, item):
        self.item = item

    def getItem(self):
        return self.item

这是我的tasks.py

from celery import shared_task
from time import sleep
from scheduler.schedulerQueue import SchedulerQ

schedulerQ = SchedulerQ()

@shared_task()
def SchedulerThread():
    print ("Starting Scheduler") 
    counter = 0
    while(1):
        counter += 1
        if(counter > 100):
            counter = 0
        schedulerQ.setItem(counter)
        print("In Scheduler thread - " + str(counter))
        sleep(2)
    print("Exiting Scheduler")

@shared_task()
def RotatorsThread():
    print ("Starting Rotators") 
    while(1):
        item = schedulerQ.getItem()
        print("In Rotators thread - " + str(item))
        sleep(2)
    print("Exiting Rotators")

@shared_task()
def setSchedulerQ(schedulerQueue):
    schedulerQ = schedulerQueue

@shared_task()
def getSchedulerQ():
    return schedulerQ

我正在我的apps.py中启动任务...我不确定这是否是正确的地方,因为任务/工人似乎无法工作,直到我在运行celery -A cesGroundStation -l info的单独控制台中启动工人为止celery -A cesGroundStation -l info

from django.apps import AppConfig
from scheduler.schedulerQueue import SchedulerQ
from scheduler.tasks import SchedulerThread, RotatorsThread, setSchedulerQ, getSchedulerQ

class SchedulerConfig(AppConfig):
    name = 'scheduler'

    def ready(self):
        schedulerQ = SchedulerQ()
        setSchedulerQ.delay(schedulerQ)
        SchedulerThread.delay()
        RotatorsThread.delay()

在我的views.py中,我有:

def schedulerQ():
    queue = getSchedulerQ.delay()
    return HttpResponse("Your list: " + queue)

django应用程序运行没有错误,但是我的“ celery -A cesGroundStation -l info” 输出是这样的: Celery命令输出

首先,它似乎启动了多个“ SchedulerThread”任务,其次,“ SchedulerQ”对象没有传递给Rotators,因为它没有读取更新的值。

如果我转到显示views.schedulerQ视图的URL,则会收到此错误: Django views error

一般而言,我对Python,Django和Web开发的经验很少,所以我不知道从上一个错误开始。 解决方案建议使用Redis将对象传递给视图,但是我不知道如何使用RabbitMQ做到这一点。 稍后在schedulerQ对象上将实现队列,并且调度程序和旋转器将充当生产者/消费者动态的角色,并显示队列内容,因此我认为使用数据库可能会占用大量资源。 如何在所有任务中共享该对象,这是否是正确的方法?

正确的方法是使用一些持久层,例如数据库或结果后端 ,以便在需要在任务之间共享信息时存储要在任务之间共享的信息(在此示例中,您当前在班级中放置的内容) )。

Celery使用分布式消息传递范例进行操作-在本示例中,提炼该想法的一种好方法是,每次分派任务时,模块将独立执行。 每当将任务分派给Celery时,您都必须假定它在单独的解释器中运行并且独立于其他任务加载。 每次都重新实例化SchedulerQ类。

您可以按照前面链接的文档中所述的方式在任务之间共享信息,并且一些最佳实践技巧讨论了数据持久性问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM