关于celery routing key的一些疑问及我的理解

自己用celery写应用也有一段时间了,celery任务路由那一块一直没理解得比较透彻。今天做了几个小实验,感觉自己对celery的路由机制清晰了一些。如果需要了解地比较深刻,还是该玩玩rabbitmq,理解AMQP协议。目前时间不允许,只能作罢。

app.conf.task_queues = {
    'login': {
        'exchange': 'login',
        'exchange_type': 'direct',
        'routing_key': 'login'
    },
    'gen_cookies': {
        'exchange': 'gen_cookies',
        'exchange_type': 'fanout'
    },
    'user': {
        'exchange': 'user',
        'exchange_type': 'topic',
        'routing_key': 'user.*'
    },
}

app.conf.task_routes = {
    'tasks.login.execute_login_task': {
        'queue': 'login',
        'serializer': 'json',
        'routing_key': 'login_all'
    },
    'tasks.login.do_login': {
        'queue': 'login',
        'serializer': 'json',
        'routing_key': 'login_each'
    },
    'tasks.login.do_gen_cookie': {
        'queue': 'gen_cookies',
        'serializer': 'json',
        'routing_key': 'gen_cookies'
    },
    'tasks.user.*': {
        'queue': 'user',
        'routing_key': 'user.all',
        'serializer': 'json'
    },
}

我们这里定义了三个task queues和三个task routes,并且使用了三种类型的exchange。在我们使用direct类型的交换机的时候,如果我们的routing_keyapp.conf.task_queues中定义的和在app.conf.task_routes中定义的不统一,那么celery会在投递消息的时候,以task_routes中定义的routing_key为准,进行投递,并且worker可以正常消费。当我们的exchange为fanout的时候,这时候不需要绑定 routing_key ,只要worker启动的时候制定了对应的queue(这里是gen_cookies),那么该worker也必然会接收到消息,并进行消费。当我们的exchange类型为 topic 的时候,routing_key就有作用了。在上述例子中,我们将user.*绑定到名为user的queue上,在task_routes中,我们的routing_keyuser.all,可以匹配上述的模式,当我们换成任意一个不匹配上述模式的routing_key,比如test,那么该消息就不会被任何的worker消费。

上述便是我目前对于celery task routes部分机制的理解。它的文档看了还是感觉不是很清晰,如果本文有误,希望读者可以指出来。