我有一个名为experiment
的RabbitMQ主题交换。我正在构建一个消费者,我希望收到路由密钥以“foo”开头的所有消息以及路由密钥以“bar”开头的所有消息。
根据RabbitMQ文档,并根据我自己在管理UI中的实验,应该可以连接一个交换,一个队列和两个绑定(foo.#
和bar.#
)它们。
我无法弄清楚如何使用Kombu的ConsumerMixin来表达这一点。我觉得我应该能做到:
q = Queue(exchange=exchange, routing_key=['foo.#', 'bar.#'])
......但它完全不喜欢这样。我也试过了:
q.bind_to(exchange=exchange, routing_key='foo.#')
q.bind_to(exchange=exchange, routing_key='bar.#')
...但每次尝试我都会得到:
kombu.exceptions.NotBoundError: Can't call method on Queue not bound to a channel
...我猜鬃毛感觉到了。但是我无法在mixin的界面中看到一个位置,一旦绑定到通道,我就可以轻松地挂钩到队列。这是基础(工作)代码:
from kombu import Connection, Exchange, Queue
from kombu.mixins import ConsumerMixin
class Worker(ConsumerMixin):
exchange = Exchange('experiment', type='topic')
q = Queue(exchange=exchange, routing_key='foo.#', exclusive=True)
def __init__(self, connection):
self.connection = connection
def get_consumers(self, Consumer, channel):
return [Consumer(queues=[self.q], callbacks=[self.on_task])]
def on_task(self, body, message):
print body
message.ack()
if __name__ == '__main__':
with Connection('amqp://guest:guest@localhost:5672//') as conn:
worker = Worker(conn)
worker.run()
...哪个有效,但只给我foo
条消息。除了为我感兴趣的每个路由密钥创建一个新的Queue并将它们全部传递给Consumer之外,还有一种干净的方法吗?
答案 0 :(得分:7)
经过一番挖掘后,我找到了一种方法来实现这一点,这与我的第一个想法非常接近。不是将routing_key
字符串传递给队列,而是传递bindings
列表。列表中的每个元素都是binding
对象的实例,用于指定交换和路由密钥。
一个例子胜过千言万语:
from kombu import Exchange, Queue, binding
exchange = Exchange('experiment', type='topic')
q = Queue(exchange=exchange, bindings=[
binding(exchange, routing_key='foo.#'),
binding(exchange, routing_key='bar.#')
], exclusive=True)
它很棒!