標籤:
RabbitMQ(三) -- Publish/Subscribe
`rabbitmq`支援一對多的模式,一般稱為發布/訂閱。也就是說,生產者產生一條訊息後,`rabbitmq`會把該訊息分發給所有的消費者。
Exchanges
之前的教程中,僅僅使用了基本的訊息模型:
- 生產者產生訊息
- 把訊息添加到訊息佇列
- 消費者接收訊息
而在`rabbitmq完整的訊息模型`中,並不是這樣的。事實上,生產者並不知道訊息是否發送到隊列,而是把訊息直接發送給`Exchanges`。
`Exchanges`的功能理解起來非常簡單,它只負責接收生產者發送的資料並把這些資料添加到訊息佇列。但是,在存在多個訊息佇列的情況下,`Exchanges`必須知道每條訊息要添加到哪一個訊息佇列。
`rabbitmq`提供了幾種`Exchanges`,包括:`direct`, `topic`, `headers` and `fanout`。
這裡,僅僅介紹fanout的使用。
channel.exchange_declare(exchange=‘news‘, type=‘fanout‘)
那麼,發布訊息:
channel.basic_publish(exchange=‘news‘, routing_key=‘‘, body=message)
Temporary queues
由於在生產者和消費者中需要指定相同的訊息佇列才能實現訊息通訊,那麼如果不特殊指定某個訊息佇列會如何呢?
那麼需要使用預設參數讓系統給產生一個特定的訊息佇列。
result = channel.queue_declare()
Bindings
為了發送指定發送的訊息佇列,必須建立exchange和訊息佇列之間的關係:
channel.queue_bind(exchange=‘news‘, queue=result.method.queue)
例子
作為生產者的publish:
#!/usr/bin/env python# coding=utf-8import pikaimport sysconnection = pika.BlockingConnection(pika.ConnectionParameters(host=‘localhost‘))channel = connection.channel()channel.exchange_declare(exchange=‘news‘,type=‘fanout‘)for i in range(100): message = str(i) + ‘Hello World!‘ channel.basic_publish(exchange=‘news‘, routing_key=‘‘, body=message) print " [x] Sent %r" % (message,) import time time.sleep(2)connection.close()
作為消費者的subscribe:
#!/usr/bin/env python# coding=utf-8import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters(host=‘localhost‘))channel = connection.channel()channel.exchange_declare(exchange=‘news‘, type=‘fanout‘)result = channel.queue_declare(exclusive=True)queue_name = result.method.queuechannel.queue_bind(exchange=‘news‘,queue=queue_name)print ‘ [*] Waiting for news. To exit press CTRL+C‘def callback(ch, method, properties, body): print " [x] %r" % (body,)channel.basic_consume(callback, queue=queue_name, no_ack=True)channel.start_consuming()
RabbitMQ(三) -- Publish/Subscribe