【问题标题】:Celery, route all tasks in a Django project to a specific queueCelery,将 Django 项目中的所有任务路由到特定队列
【发布时间】:2016-04-19 22:52:54
【问题描述】:

我有一台运行同一个 Django 项目的两个副本的机器,我们称它们为 AB,我想使用 Celery 来处理后台任务。

我设置主管启动两个工作人员,每个项目一个,但鉴于两个项目中的任务名称相同,有时任务由错误的工作人员运行。

我的下一步是使用-Q queueName 参数为每​​个工人使用不同的队列。使用rabbitmqctl list_queues 我可以看到两个队列都已创建。我用来发布工人的命令是

python3 -m celery worker -A project -l INFO -Q q1 --hostname=celery1@ubuntu

python3 -m celery worker -A project -l INFO -Q q2 --hostname=celery2@ubuntu

问题是,我如何将所有任务从 project A 路由到 queue A,并将所有任务从 project B 路由到 队列B?是的,我看到您可以向 task 装饰器添加一个参数来选择队列,但我正在寻找一个全局设置或类似的东西。

编辑 1:我尝试使用 CELERY_DEFAULT_QUEUE,但它不起作用,设置被忽略。我也尝试过创建一个哑路由器,如下所示:

class MyRouter(object):
    def route_for_task(self, task, args=None, kwargs=None):
        return 'q1'

CELERY_ROUTES = (MyRouter(), )

而且它有效(显然在每个项目中返回不同的队列),但我很困惑,为什么 CELERY_DEFAULT_QUEUE 设置被忽略了?

【问题讨论】:

    标签: django rabbitmq celery


    【解决方案1】:

    最后它比我预期的要容易。我只需要设置默认队列和默认路由键(以及可选的默认交换,只要它是 direct 交换)。

    CELERY_DEFAULT_QUEUE = 'q2'
    CELERY_DEFAULT_EXCHANGE = 'q2'
    CELERY_DEFAULT_ROUTING_KEY = 'q2'
    

    我有些概念不清楚,但是在关注official RabbitMQ's tutorials之后,他们变得更加清晰,我能够解决问题。

    【讨论】:

    • 天哪,你无法想象在同样的问题上苦苦挣扎后,我差点把头砸碎。现在更令人困惑了,因为 celery 4.4 有一组不同的变量(CELERY_TASK_DEFAULT_QUEUE、CELERY_TASK_DEFAULT_EXCHANGE、CELERY_TASK_DEFAULT_ROUTING_KEY),还有一些过时的文档,很难理解你的 celery 版本应该做什么。无论如何,您的解决方案有效,谢谢!
    • 谢谢。几个小时的相同问题在日志中出现错误的“收到类型未注册的任务......”。在时间线上,最终构建了一个单独的 vm,因为两个 django 应用程序的 id 指向不同的 obj,导致各种悲伤,但只是有时。降落后不久。
    【解决方案2】:

    您可以将任务路由定义为

    CELERY_ROUTES = {
        'services.qosservice.*': {'queue': 'qos_celery'},
    }
    

    * 是 celery 支持的通配符。

    参考:http://docs.celeryproject.org/en/latest/userguide/routing.html#automatic-routing

    【讨论】:

      【解决方案3】:

      我认为你必须在 settings.py 中定义路由

      CELERY_ROUTES = {
      
          'services.qosservice.set_qos_for_vm': {'queue': 'qos_celery'},
      
          'services.qosservice.qos_recovery': {'queue': 'qos_celery'},
      
          'services.qosservice.qos_recovery_compute': {'queue': 'qos_celery_1'},
      
      }
      

      在我的例子中。任务 set_qos_for_vm 将路由到 qos_celery 队列,任务 qos_recovery_compute 队列将路由到 qos_celery_1。

      更多详情:http://docs.celeryproject.org/en/latest/userguide/routing.html#id2

      希望对你有帮助

      【讨论】:

      • 我必须列出所有任务吗?没有通配符之类的东西吗?
      猜你喜欢
      • 2012-04-22
      • 2019-01-08
      • 2015-06-16
      • 2013-06-02
      • 2019-11-19
      • 2020-05-12
      • 1970-01-01
      • 2020-04-06
      相关资源
      最近更新 更多