Celery动态队列的创建和路由

时间:2012-08-09 11:52:17

标签: python rabbitmq celery

我尝试调用任务并为该任务创建一个队列(如果它不存在),然后立即将该被调用的任务插入该队列。我有以下代码:

@task
def greet(name):
    return "Hello %s!" % name


def run():
    result = greet.delay(args=['marc'], queue='greet.1',
        routing_key='greet.1')
    print result.ready()

然后我有一个自定义路由器:

class MyRouter(object):

    def route_for_task(self, task, args=None, kwargs=None):
        if task == 'tasks.greet':
            return {'queue': kwargs['queue'],
                    'exchange': 'greet',
                    'exchange_type': 'direct',
                    'routing_key': kwargs['routing_key']}
        return None

这将创建一个名为greet.1的交换和一个名为greet.1的队列,但队列为空。交换应该只调用greet,它知道如何将greet.1之类的路由密钥路由到名为greet.1的队列。

有什么想法吗?

1 个答案:

答案 0 :(得分:13)

执行以下操作时:

task.apply_async(queue='foo', routing_key='foobar')

然后Celery将从CELERY_QUEUES中的'foo'队列中获取默认值, 或者如果它不存在则自动使用(queue = foo,exchange = foo,routing_key = foo)

创建它

因此,如果CELERY_QUEUES中不存在'foo',您将最终得到:

queues['foo'] = Queue('foo', exchange=Exchange('foo'), routing_key='foo')

然后,生产者将声明该队列,但由于您覆盖了routing_key, 实际上使用routing_key = 'foobar'

发送邮件

这可能看起来很奇怪,但这种行为实际上对主题交换非常有用, 您在哪里发布到不同的主题。

尽管你想做的事情比较困难,你可以自己创建队列 并声明它,但这不适用于自动消息发布重试。 如果apply_async的队列参数可以支持,那会更好 相反,自定义kombu.Queue将被声明并用作目标。 也许你可以在http://github.com/celery/celery/issues

打开一个问题