芹菜任务被发送到多个队列

时间:2015-10-28 19:45:25

标签: python redis celery

我注意到芹菜已经将任务发送到多个队列,两个队列中的工作人员一直在执行任务。

我的队列定义是:

CELERY_QUEUES = (
    Queue('default', Exchange('default'), routing_key='default'),
    Queue('client1', Exchange('client1'), routing_key='client1'),
    Queue('images', Exchange('media'), routing_key='media.images'),
)

当我停止所有工人后,我跑了:

>>> tasks.ping.apply_async(queue='default')

我可以看到该任务出现在 defaultclient1队列中:

$ redis-cli -c llen default
(integer) 1
$ redis-cli -c llen client1
(integer) 1

这仅适用于default队列。直接将其发送到client1队列只会将其添加到那里:

>>> tasks.ping.apply_async(queue='client1')
$ redis-cli -c llen default
(integer) 1
$ redis-cli -c llen client1
(integer) 2

images队列永远不会错误地接收任务。

这是Celery 3.1.15与Redis经纪人。

1 个答案:

答案 0 :(得分:8)

好!看起来问题是Kombu的Redis经纪人没有清除旧的交易所+路由密钥。

最初我配置了队列:

CELERY_QUEUES = (
    Queue('default', Exchange('default'), routing_key='default'),
    Queue('client1', Exchange('default'), routing_key='default'),
)

后来将它们更改为client1使用单独的交换和路由键。

但由于某些原因,Kombu没有清除旧的绑定,所以我留下了:

redis> smembers _kombu.binding.default
1) "default\x06\x16\x06\x16client1"
2) "default.client1\x06\x16\x06\x16client1"
3) "default\x06\x16\x06\x16default"

因此,发送到default的任务被路由到defaultclient1个队列。

解决方法是删除不正确的绑定:

redis> srem _kombu.binding.default "default\x06\x16\x06\x16client1"
redis> srem _kombu.binding.default "default.client1\x06\x16\x06\x16client1"