rabbitMQ說明文檔
rabbitMQ是什麼
RabbitMQ 是由 LShift 提供的一個 Advanced Message Queuing Protocol (AMQP)的開源實現,由以高性能、健壯以及可伸縮性出名的 Erlang 寫成(因此也是繼承了這些優點)。
首先介紹 AMQP 和一些基本概念:
當前各種應用大量使用異步消息模型,並隨之產生衆多消息中間件產品及協議,標準的不一致使應用與中間件之間的耦合限制產品的選擇,並增加維護成本。 AMQP 是一個提供統一消息服務的應用層標準協議,基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端 / 中間件不同產品,不同開發語言等條件的限制。 當然這種降低耦合的機制是基於與上層產品,語言無關的協議。 AMQP 協議是一種二進制協議,提供客戶端應用與消息中間件之間異步、安全、高效地交互。從整體來看, AMQP 協議可劃分爲三層。
這種分層架構類似於 OSI 網絡協議,可替換各層實現而不影響與其它層的交互。AMQP 定義了合適的服務器端域模型,用於規範服務器的行爲 (AMQP 服務器端可稱爲 broker) 。
Model 層決定這些基本域模型所產生的行爲,這種行爲在 AMQP 中用 ”command”表示,在後文中會着重來分析這些域模型。
Session 層定義客戶端與 broker 之間的通信 ( 通信雙方都是一個 peer ,可互稱做partner) ,爲 command 的可靠傳輸提供保障。
Transport 層專注於數據傳送,並與 Session 保持交互,接受上層的數據,組裝成二進制流,傳送到 receiver 後再解析數據,交付給 Session 層。 Session 層需要Transport 層完成網絡異常情況的彙報,順序傳送 command 等工作。
AMQP 當中有四個概念非常重要:虛擬主機( virtual host ),交換機( exchange),隊列( queue )和綁定( binding )。
虛擬主機( virtual host ):一個虛擬主機持有一組交換機、隊列和綁定。爲什麼需要多個虛擬主機呢? RabbitMQ 當中,用戶只能在虛擬主機的粒度進行權限控制。因此,如果需要禁止 A 組訪問 B 組的交換機 / 隊列 / 綁定,必須爲 A 和 B 分別創建一個虛擬主機。每一個 RabbitMQ 服務器都有一個默認的虛擬主機 “/” 。
隊列( Queue ):由消費者建立的,是 messages 的終點,可以理解成裝消息的容器。消息一直存在隊列裏,直到有客戶端或者稱爲 Consumer 消費者連接到這個隊列並將 message 取走爲止。隊列可以有多個。
交換機( Exchange ):可以理解成具有路由表的路由程序。每個消息都有一個路由鍵( routing key ),就是一個簡單的字符串。交換機中有一系列的綁定( binding),即路由規則( routes )。交換機可以有多個。多個隊列可以和同一個交換機綁定,同時多個交換機也可以和同一個隊列綁定。(多對多的關係)
三種交換機:
1. Fanout Exchange (不處理路由鍵):一個發送到交換機上的消息都會被轉發到與該交換機綁定的所有隊列上。 Fanout 交換機發消息是最快的。
2. Direct Exchange (處理路由鍵):如果一個隊列綁定到該交換機上,並且當前要求路由鍵爲 X ,只有路由鍵是 X 的消息纔會被這個隊列轉發。
3. Topic Exchange (將路由鍵和某模式進行匹配,可以理解成模糊處理):路由鍵的詞由 “.” 隔開,符號 “#” 表示匹配 0 個或多個詞,符號 “*” 表示匹配不多不少一個詞。因此 “ audit.# ” 能夠匹配到 “ audit.irs.corporate ” ,但是 “ audit.* ” 只會匹配到 “ audit.irs ”
具體例子可以看下圖
持久化:隊列和交換機有一個創建時候指定的標誌durable,直譯叫做堅固的。durable的唯一含義就是具有這個標誌的隊列和交換機會在重啓之後重新建立,它不表示說在隊列當中的消息會在重啓後恢復。那麼如何才能做到不只是隊列和交換機,還有消息都是持久的呢?
但是首先一個問題是,你真的需要消息是持久的嗎?對於一個需要在重啓之後回覆的消息來說,它需要被寫入到磁盤上,而即使是最簡單的磁盤操作也是要消耗時間的。如果和消息的內容相比,你更看重的是消息處理的速度,那麼不要使用持久化的消息。
當你將消息發佈到交換機的時候,可以指定一個標誌“Delivery Mode”(投遞模式)。根據你使用的AMQP的庫不同,指定這個標誌的方法可能不太一樣。簡單的說,就是將 Delivery Mode設置成2,也就是持久的即可。一般的AMQP庫都是將Delivery Mode設置成1,也就是非持久的。所以要持久化消息的步驟如下:
1. 將交換機設成 durable 。
2. 將隊列設成 durable 。
3. 將消息的 Delivery Mode 設置成 2 。
綁定( Bindings )如何持久化?我們無法在創建綁定的時候設置成 durable 。沒問題,如果綁定了一個 durable 的隊列和一個 durable 的交換機, RabbitMQ 會自動保留這個綁定。類似的,如果刪除了某個隊列或交換機(無論是不是 durable ),依賴它的綁定都會自動刪除。
注意兩點:
1. RabbitMQ 不允許綁定一個非堅固( non-durable )的交換機和一個 durable 的隊列。反之亦然。要想成功必須隊列和交換機都是 durable 的。
2. 一旦創建了隊列和交換機,就不能修改其標誌了。例如,如果創建了一個 non-durable 的隊列,然後想把它改變成 durable 的,唯一的辦法就是刪除這個隊列然後重現創建。因此,最好仔細檢查創建的標誌。
消息隊列(MQ)使用過程
幾個概念說明:
1. Broker:簡單來說就是消息隊列服務器實體。
2. Exchange:消息交換機,它指定消息按什麼規則,路由到哪個隊列。
3. Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
4. Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
5. Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
6. vhost:虛擬主機,一個broker裏可以開設多個vhost,用作不同用戶的權限分離。
7. producer:消息生產者,就是投遞消息的程序。
8. consumer:消息消費者,就是接受消息的程序。
9. channel:消息通道,在客戶端的每個連接裏,可建立多個channel,每個channel代表一個會話任務。
消息隊列的使用過程大概如下:
1. 客戶端連接到消息隊列服務器,打開一個channel。
2. 客戶端聲明一個exchange,並設置相關屬性。
3. 客戶端聲明一個queue,並設置相關屬性。
4. 客戶端使用routing key,在exchange和queue之間建立好綁定關係。
5. 客戶端投遞消息到exchange。
6. exchange接收到消息後,就根據消息的key和已經設置的binding,進行消息路由,將消息投遞到一個或多個隊列裏。