傳統的隊列消息服務,有三個概念,生產者,消費者,隊列;rabbitMQ在概念上多做了一層抽象,在發消息者和隊列之間,加入了交換器。
消息是先發到交換器,由交換器再根據調度策略再把消息給隊列;
rabbitMQ重要概念:
虛擬主機(Virtual Host):
相當於mini版的rabbitMQ服務,每個虛擬機中都包含交換機、對接、綁定。
創建用戶並分配對應的虛擬機以達到權限控制,不同的用戶之間不會相互影響。
交換機(Exchange):
根據策略及路由鍵發送消息到對應的隊列,如果沒有綁定隊列,則直接丟棄掉發過來的消息;
路由鍵(routing key):
作爲交換機發送消息到隊列的key,根據路由鍵+交換機策略,將消息發送至對應的隊列;
綁定(Binding):
隊列需要和交換機進行綁定,多對多的關係;
Exchange分發策略:
direct:
完全匹配模式,即路由鍵與隊列名稱完全匹配,交換機會把消息發送給與路由鍵名字一致的隊列;
fanout:
多播模式,不處理路由鍵,會發送給所有綁定了該交換機的隊列;
topic:
模糊匹配模式,路由鍵、隊列名都以"."標識符分隔,以“*”,“#”進行匹配,“*”表示一個,“#”表示0或多個;
我們準備發送關於動物的消息。消息會附加一個選擇鍵包含3個標識符(兩個點隔開)。
第一個標識符描述動物的速度,第二個標識符描述動物的顏色,第三個標識符描述動物的物種:<speed>.<color>.<species>。
我們創建3個綁定鍵:Q1與*.orange.*綁定Q2與*.*.rabbit和lazy.#綁定。
可以簡單的認爲:
Q1對所有的橙色動物感興趣。
Q2想要知道關於兔子的一切以及關於懶洋洋的動物的一切。
quick.orange.rabbit的選擇鍵的消息將會被轉發到兩個隊列。
lazy.orange.elephant的消息也會被轉發到兩個隊列。
quick.orange.fox只會被轉發到Q1。
lazy.brown.fox將會被轉發到Q2。
lazy.pink.rabbit雖然與兩個綁定鍵匹配,但是也只會被轉發到Q2一次。
quick.brown.fox不能與任何綁定鍵匹配,所以會被丟棄。
發送一個或者四個標識符的選擇鍵,類似:orange,quick.orange.male.rabbit,這些選擇鍵不能與任何綁定鍵匹配,所以消息將會被丟棄。
另一方面,lazy.orange.male.rabbit,雖然是四個標識符,也可以與lazy.#匹配,從而轉發至Q2。
注:主題類型的轉發器非常強大,可以實現其他類型的轉發器。
當一個隊列與綁定鍵#綁定,將會收到所有的消息,類似fanout類型轉發器。
當綁定鍵中不包含任何#與*時,類似direct類型轉發器。
消息確認機制:
生產者確認機制:
在使用rabbitMQ過程中,可以使用消息持久化操作來解決因爲服務器的異常導致信息丟失。但生產者消息發送出去後,默認情況下是生產者是不清楚消息是否真正到達隊列的。rabbitMQ提供了兩種方式解決;
通過事務機制實現:
使用txSelect(),txCommit(),txRollback()方法;但該方式耗時較長
通過將交換機設置成confirm模式實現:
設置exange爲confirm模式,當消息被投遞到匹配的隊列之後,就會發送一個確認給生產者;如果消息是可持久化的,那麼確認消息會在寫入磁盤之後發出。confirm模式最大的好處在於他是異步的,生產者可以通過回調方法來處理該確認消息,如果因爲rabbitMQ自身內部原因導致丟失,會發送一條nack消息,同樣可以在回調方法中處理;
消費者確認機制:
消費者在聲明隊列時,可以指定toack參數,爲true,則是自動應答;false手動應答;
自動應答就是當消息被消費後,即RabbitMQ會進行刪除消息;如果當消息處理過程中出現宕機或者其他原因導致該消息沒有處理完畢,則該消息就丟失了。
手動應答,則是需要顯示發揮ack信號,如消息被消費後,消費端並沒有發回ack信號且消費者斷開,則rabbitMQ會將消息重新進入隊列等待下一個消費者;
這樣就能保證每個消息都能正常處理了;