1. 程式人生 > >RabbitMQ基本概念和使用

RabbitMQ基本概念和使用

RabbitMQ是一個訊息代理,核心原理:傳送訊息,接收訊息。

RabbitMQ主要用於元件之間的解耦,訊息傳送者無需知道訊息使用者的存在,反之亦然。

              單向解耦                                        雙向解耦(如:RPC)

例如一個日誌系統,很容易使用RabbitMQ簡化工作量,一個Consumer進行訊息的正常處理,另一個Consumer複製對訊息進行日誌記錄,只要在程式中指定兩個Consumer所監聽的queue以相同的方式繫結到同一個exchange即可,剩下的訊息分發工作由RabbitMQ完成。

安裝rabbitmq,請參考

官網

首先通過一個非常簡單的”hello world“例子介紹如何使用RabbitMQ,然後再介紹其涉及的基本概念並對交換機和佇列多做點介紹。

一、helloworld例子

本例非常簡單——傳送一個訊息”hello world“,然後獲取它並輸出到螢幕。

總共需要兩個程式,一個傳送訊息叫send.py,一個接受訊息並列印訊息內容叫receive.py。

該圖為helloworld例子的原理圖:生產者send.py(Productor)把訊息(”hello world“)傳送到一個名為”queue“的佇列中,消費者receive.py從這個佇列中獲取訊息。接下來看程式碼:

send.py(傳送訊息)

#!/usr/bin/env python
import pika
#第一步,連線RabbitMq伺服器
rabbit_username='xxx' 
rabbit_password='xxx'
credentials = pika.PlainCredentials(rabbit_username, rabbit_password) 
connection = pika.BlockingConnection(pika.ConnectionParameters( host='x.x.x.x',credentials=credentials))
#channel是進行訊息讀寫的通道 channel
= connection.channel() #第二步,建立一個名為queue的佇列,然後把訊息傳送到這個佇列 channel.queue_declare(queue='queue') #第三步,現在可以傳送訊息,但是RabbitMQ不能把訊息直接傳送到佇列,要傳送到交換器,這個稍後介紹,這裡使用預設交換器(exchange),它使用一個空字串標
#識,routing_key引數必須指定為佇列名稱,這裡為queue
channel.basic_publish(exchange='', routing_key='queue', body='hello world') print "send.py:send message 'hello world',wait for receive.py deal with this message" #退出程式前,通過關閉連線保證訊息已經投遞到RabbitMq connection.close()

receive.py(獲取資料)

#!/usr/bin/env python
import pika

#第一步,同樣連線RabbitMq伺服器
rabbit_username='xxx'
rabbit_password='xxx'
credentials = pika.PlainCredentials(rabbit_username, rabbit_password)
connection = pika.BlockingConnection(pika.ConnectionParameters( host='x.x.x.x',credentials=credentials))
channel = connection.channel()

#為確保佇列存在,再次執行queue_declare建立一個佇列,我們可以多次執行該命令,但是隻有一個佇列會建立
#因為不能保證send.py先執行還是receive.py先執行,所以重複宣告佇列來確保其存在
channel.queue_declare(queue='queue')


#第三步,定義一個回撥函式,當獲得訊息時,Pika庫呼叫這個回撥函式來處理訊息,該回調函式將訊息內容列印到螢幕
def callback(ch, method, properties, body):
    print "receive.py: Received message %r" % (body,)

#第四步,告訴rabbbitMq回撥函式將從queue佇列接收訊息
channel.basic_consume(callback,
                      queue='queue',
                      no_ack=True)

#第五步,輸入一個無限迴圈來等待訊息資料並執行回撥函式
print ' [*] Waiting for messages. To exit press CTRL+C'
channel.start_consuming()

現在在終端執行程式。首先,用send.py傳送一條訊息:

$ python send.py 
send.py:send message 'hello world',wait for receive.py deal with this message

生產者(producer)程式send.py每次執行後就會停止。現在執行receive.py來接收訊息:

$ python receive.py 
receive.py: Received message 'hello world'
 [*] Waiting for messages. To exit press CTRL+C

成功了!現在已經通過RabbitMQ傳送了第一條訊息。但是receive.py程式並沒有退出,它一直在準備獲取訊息,可以通過ctrl-c來中斷它。

二、RabbitMQ基本概念

總結一下發送接收訊息的過程:

通過上面例子對RabbitMQ有一個感性認識後,現在來介紹RabbitMQ中的基本概念。

Broker:訊息佇列伺服器實體

訊息:每個訊息都有一個路由鍵(routing key)的屬性。就是一個簡單的字串。

connection:應用程式與broker的網路連線。

channel:幾乎所有的操作都在channel中進行,channel是進行訊息讀寫的通道。客戶端可建立多個channel,每個channel代表一個會話任務。

交換機:接收訊息,根據路由鍵轉發訊息到繫結的佇列

繫結:一個繫結就是基於路由鍵將交換機和佇列連線起來的路由規則,所以交換機不過就是一個由繫結構成的路由表。

舉例:一個具有路由鍵“key1”的訊息要傳送到兩個佇列,queueA和queueB。要做到這點就要建立兩個繫結,每個繫結連線一個交換機和一個佇列。兩者都是由路由鍵“key1”觸發,這種情況,交換機會複製一份訊息並把它們分別傳送到兩個佇列中。

佇列:訊息的容器,也是訊息的終點。一個訊息可投入一個或多個佇列