Django Celery delay()总是推送到默认的'celery'队列

时间:2017-06-15 22:39:54

标签: python django celery django-celery celery-task

我正用这个撕开我的头发。

我的问题的关键在于,使用我的CELERY_DEFAULT_QUEUE中的Django settings.py设置并不强制我的任务转到我设置的特定队列。它总是进入我的代理中的默认celery队列。

但是,如果我在queue=proj:dev装饰器中指定shared_task,它将转到正确的队列。它表现得像预期的那样。

我的设置如下:

  • 我的localhost上的Django代码(用于测试和填充)。通过Django的shell(.delay()
  • 执行任务manage.py shell
  • 配置为我的经纪人的远程Redis实例
  • 2名芹菜工人在远程机器设置上配置并等待来自Redis的消息(在Google App Engine上 - 可能与此无关)

注意:对于下面的代码,我模糊了项目名称并使用proj作为占位符。

celery.py

from __future__ import absolute_import, unicode_literals

import os
from celery import Celery, shared_task

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

app = Celery('proj')

app.config_from_object('django.conf:settings', namespace='CELERY', force=True)

app.autodiscover_tasks()


@shared_task
def add(x, y):
    return x + y

settings.py

...
CELERY_RESULT_BACKEND = 'django-db'
CELERY_BROKER_URL = 'redis://:{}@{}:6379/0'.format(
    os.environ.get('REDIS_PASSWORD'),
    os.environ.get('REDIS_HOST', 'alice-redis-vm'))
CELERY_DEFAULT_QUEUE = os.environ.get('CELERY_DEFAULT_QUEUE', 'proj:dev')

我的想法是,就目前而言,我希望为我的代码所在的不同环境设置不同的队列:dev,staging,prod。因此,在Google App Engine上,我定义了一个基于各个App Engine服务传递的环境变量。

步骤

因此,通过上述配置,我使用./manage.py shell启动shell并运行add.delay(2, 2)。我得到了AsyncResult,但Redis监控器清楚地显示了一条消息被发送到默认的celery队列:

1497566026.117419 [0 155.93.144.189:58887] "LPUSH" "celery"
...

我错过了什么?

不要在工作中投入扳手,但我觉得今天有一点实际上正在发挥作用。但对于我的生活,我无法想象我的大脑中有哪一部分让我失望。

堆栈版本:

  • python:3.5.2
  • celery:4.0.2
  • redis:2.10.5
  • django:1.10.4

2 个答案:

答案 0 :(得分:4)

这个问题比我想象的要简单得多 - 不正确的文档!!

Celery文档要求我们使用public void nativeKeyPressed(NativeKeyEvent e) { String keyText = NativeKeyEvent.getKeyText(e.getKeyCode()); switch(keyText){ case "Escape": //close code (esc key) System.out.println("Pressed esc"); System.exit(0); break; case "P": //pause code (p key) System.out.println("Pressed p"); run = !run; check(); break; case "C": //copy code (c key) System.out.println("Pressed c"); StringSelection ss = new StringSelection(MouseInfo.getPointerInfo().getLocation().toString().replaceAll("java.awt.Point", "").replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("=", "").replaceAll("x", "").replaceAll("y", "").replaceAll(",", ", ")); //get mouse coordinates and set them as a StringSelection Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); //get the clipboard cb.setContents(ss, ss); //set what is copied to the current mouse coordinates break; } } public void nativeKeyReleased(NativeKeyEvent e) { } 在celery对象上设置CELERY_DEFAULT_QUEUE配置。

参考:http://docs.celeryproject.org/en/latest/userguide/configuration.html#new-lowercase-settings

我们目前应该使用task_default_queue。这是所有其他设置命名的不一致之处。名。它是在Github上提出的 - https://github.com/celery/celery/issues/3772

解决方案摘要

在配置模块中使用CELERY_TASK_DEFAULT_QUEUE(使用CELERY_DEFAULT_QUEUE)对队列没有影响。

改为使用config_from_object

答案 1 :(得分:0)

如果您来到这里是因为您尝试在 Celery 中使用 SQS 实现一个预定义的队列,并且发现无论您说什么,Celery 都会在 SQS 中创建一个名为“celery”的新队列,那么您已经到达了旅程的终点朋友。

在将 broker_transport_options 传递给 Celery 之前,更改您的默认队列和/或指定您将显式使用的队列。就我而言,我只需要一个队列,因此执行以下操作:

celery.conf.task_default_queue = "<YOUR_PREDEFINED_QUEUE_NAME_IN_SQS">