rabbitmq消息轉發模式1

翻譯:呂嘉偉

生產者(producer):發送消息的應用;

消息隊列(queue):保存隊列的緩衝區;

消費者(consumer):接收消息的應用。

廣播模式(fanout)

Rabbitmq的核心思想是生產者不會直接向隊列發送消息,事實上,生產者不需要關心消息最終發送到了哪個隊列中。

相反地,生產者只會將消息發送給exchange,exchange從生產者接受消息,然後轉發給隊列。Exchange知道如何處理收到的消息,要麼將它插入到某個特殊的隊列中,或是添加到多個隊列中,或是丟棄。這一切取決於的exchange的類型。

Exchange的類型主要有direct、topic、headers和fanout。可通過如下方式構造一個廣播的exchange:

channel.exchange_declare(exchange='logs',
                         type='fanout')

無名的exchange

在上面的代碼中我們聲明瞭一個“log”exchange,在應用中還存在默認的exchange,示例如下:

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body=message)

該exchange爲一個空字符,這表明消息會發往hello隊列。

現在將生產者發送的消息傳遞給logexchange:

channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)

對於廣播類型的消息,可能只會關心當前的消息,而不關心歷史消息。因此可以創建一個臨時的隊列,並且在消費者與隊列斷連時將隊列清除,示例如下:

# 聲明一個任意名稱的臨時隊列
result = channel.queue_declare(exclusive=True)

現在已經創建一個廣播類型exchange及一個臨時的隊列,此時由消費者將監聽的隊列與exchange進行綁定,示例如下:

channel.queue_bind(exchange='logs',
                   queue=result.method.queue)

生產者  emit_log.py

#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         type='fanout')

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)
print(" [x] Sent %r" % message)
connection.close()

如代碼中所示,在建立連接之後,我們聲明瞭exchange。這一步是必要的,因爲禁止將消息發給一個不存在的exchange。如果沒有隊列綁定到exchange上,消息會被丟棄。

消費者    receive_logs.py

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         type='fanout')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

channel.queue_bind(exchange='logs',
                   queue=queue_name)

print(' [*] Waiting for logs. 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()





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章