2016-05-13 58 views
3

我有一個名爲experiment的RabbitMQ主題交換。我正在構建一個消費者,我希望接收所有以「foo」開頭的路由鍵和其路由鍵以「bar」開頭的消息。使用Kombu ConsumerMixin,如何聲明多個綁定?

根據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:[email protected]:5672//') as conn: 
     worker = Worker(conn) 
     worker.run() 

...它的工作原理,但只給了我foo消息。除了爲我感興趣的每個路由鍵創建一個新的隊列並將它們全部傳遞給消費者外,是否有乾淨的方法來執行此操作?

回答

5

挖了一點點之後,我找到了一種方法來實現這一點,這與我的第一個想法非常接近。而不是將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) 

而且它的偉大工程!

+0

您應該不需要爲'Queue'提供'exchange'參數,因爲您提供的是'binding'參數? – naoko