談談RabbitMQ的相關概念

一、RabbitMQ 簡介

RabbitMQ 是採用 Erlang 語言實現 AMQP(Advanced Message Queuing Protocol,高級消息隊列協議)的消息中間件,它最初起源於金融系統,用於在分佈式系統中存儲轉發消息。RabbitMQ服務器是用Erlang語言編寫的,而羣集和故障轉移是構建在開放電信平臺框架上的。所有主要的編程語言均有與代理接口通訊的客戶端庫。RabbitMQ是一套開源(MPL)的消息隊列服務軟件,是由 LShift 提供的一個 Advanced Message Queuing Protocol (AMQP) 的開源實現,由以高性能、健壯以及可伸縮性出名的 Erlang 寫成。 ——來源百度百科

RabbitMQ 發展到今天,被越來越多的人認可,這和它在易用性、擴展性、可靠性和高可用性等方面的卓著表現是分不開的。RabbitMQ 的特點可以概括爲以下幾點:

  • 可靠性: RabbitMQ使用一些機制來保證消息的可靠性,如持久化、傳輸確認及發佈確認等。
  • 擴展性: 多個RabbitMQ節點可以組成一個集羣,也可以根據實際業務情況動態地擴展集羣中節點。
  • 高可用性: 隊列可以在集羣中的機器上設置鏡像,使得在部分節點出現問題的情況下隊列仍然可用。
  • 靈活的路由: 在消息進入隊列之前,通過交換器來路由消息。對於典型的路由功能,RabbitMQ 己經提供了一些內置的交換器來實現。針對更復雜的路由功能,可以將多個交換器綁定在一起,也可以通過插件機制來實現自己的交換器。這個後面會在我們將 RabbitMQ 核心概念的時候詳細介紹到。
  • 支持多種協議: RabbitMQ 除了原生支持 AMQP 協議,還支持 STOMP、MQTT 等多種消息中間件協議。
  • 多語言客戶端: RabbitMQ幾乎支持所有常用語言,比如 Java、Python、Ruby、PHP、C#、JavaScript等。
  • 插件機制: RabbitMQ 提供了許多插件,以實現從多方面進行擴展,當然也可以編寫自己的插件。感覺這個有點類似 Dubbo 的 SPI機制。
  • 易用的管理界面: RabbitMQ提供了一個易用的用戶界面,使得用戶可以監控和管理消息、集羣中的節點等。在安裝RabbitMQ 的時候會介紹到,安裝好 RabbitMQ 就自帶管理界面。
     

二、RabbitMQ 核心概念

RabbitMQ 整體上是一個生產者與消費者模型,主要負責接收、存儲和轉發消息。可以把消息傳遞的過程想象成:當你將一個包裹送到郵局,郵局會暫存並最終將郵件通過郵遞員送到收件人的手上,RabbitMQ就好比由郵局、郵箱和郵遞員組成的一個系統。從計算機術語層面來說,RabbitMQ 模型更像是一種交換機模型。下圖是RabbitMQ 的整體模型架構:

1.  生產者 和 消費者

Producer(生產者) : 生產消息的一方
Consumer(消費者) : 消費消息的一方

消息一般由 2 部分組成:消息頭(或者說是標籤 Label)和 消息體。消息體也可以稱爲 payLoad ,消息體是不透明的,而消息頭則由一系列的可選屬性組成,這些屬性包括 routing-key(路由鍵)、priority(相對於其他消息的優先權)、delivery-mode(指出該消息可能需要持久性存儲)等。生產者把消息交由 RabbitMQ 後,RabbitMQ 會根據消息頭把消息發送給感興趣的消費者。

2. Exchange(交換器)

在 RabbitMQ 中,消息並不是直接被投遞到 Queue(消息隊列) 中的,中間還必須經過 Exchange(交換器) 這一層,Exchange(交換器) 會把我們的消息分配到對應的 Queue(消息隊列) 中。

Exchange(交換器) 用來接收生產者發送的消息並將這些消息路由給服務器中的隊列中,如果路由不到,或許會返回給 Producer(生產者) ,或許會被直接丟棄掉 。這裏可以將RabbitMQ中的交換器看作一個簡單的實體。

RabbitMQ 的 Exchange(交換器) 有4種類型,不同的類型對應着不同的路由策略:direct(默認),fanout, topic, 和 headers,不同類型的Exchange轉發消息的策略有所區別。這個會在介紹 Exchange Types(交換器類型) 的時候介紹到。

Exchange(交換器) 示意圖如下:

生產者將消息發給交換器的時候,一般會指定一個 RoutingKey(路由鍵),用來指定這個消息的路由規則,而這個 RoutingKey 需要與交換器類型和綁定鍵(BindingKey)聯合使用才能最終生效。

RabbitMQ 中通過 Binding(綁定) 將 Exchange(交換器) 與 Queue(消息隊列) 關聯起來,在綁定的時候一般會指定一個 BindingKey(綁定建) ,這樣 RabbitMQ 就知道如何正確將消息路由到隊列了,如下圖所示。一個綁定就是基於路由鍵將交換器和消息隊列連接起來的路由規則,所以可以將交換器理解成一個由綁定構成的路由表。Exchange 和 Queue 的綁定可以是多對多的關係。

Binding(綁定) 示意圖:

生產者將消息發送給交換器時,需要一個RoutingKey,當 BindingKey 和 RoutingKey 相匹配時,消息會被路由到對應的隊列中。在綁定多個隊列到同一個交換器的時候,這些綁定允許使用相同的 BindingKey。BindingKey 並不是在所有的情況下都生效,它依賴於交換器類型,比如fanout類型的交換器就會無視,而是將消息路由到所有綁定到該交換器的隊列中。

RabbitMQ 常用的 Exchange Type 有 fanoutdirecttopicheaders 這4種類型:

  • fanout 類型的Exchange路由規則非常簡單,它會把所有發送到該Exchange的消息路由到所有與它綁定的Queue中,不需要做任何判斷操作,所以 fanout 類型是所有的交換機類型裏面速度最快的。fanout 類型常用來廣播消息。
  • direct 類型的Exchange路由規則也很簡單,它會把消息路由到那些 Bindingkey 與 RoutingKey 完全匹配的 Queue 中。direct 類型常用在處理有優先級的任務,根據任務的優先級把消息發送到對應的隊列,這樣可以指派更多的資源去處理高優先級的隊列。
  • topic類型的交換器在匹配規則上進行了擴展,它與 direct 類型的交換器相似,也是將消息路由到 BindingKey 和 RoutingKey 相匹配的隊列中。
  • headers 類型的交換器不依賴於路由鍵的匹配規則來路由消息,而是根據發送的消息內容中的 headers 屬性進行匹配。在綁定隊列和交換器時制定一組鍵值對,當發送消息到交換器時,RabbitMQ會獲取到該消息的 headers(也是一個鍵值對的形式)'對比其中的鍵值對是否完全匹配隊列和交換器綁定時指定的鍵值對,如果完全匹配則消息會路由到該隊列,否則不會路由到該隊列。headers 類型的交換器性能會很差,而且也不實用,基本上不會看到它的存在。

3. Queue(消息隊列)

Queue(消息隊列) 用來保存消息直到發送給消費者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列裏面,等待消費者連接到這個隊列將其取走。

RabbitMQ 中消息只能存儲在 隊列 中,這一點和 Kafka 這種消息中間件相反。Kafka 將消息存儲在 topic(主題) 這個邏輯層面,而相對應的隊列邏輯只是topic實際存儲文件中的位移標識。 RabbitMQ 的生產者生產消息並最終投遞到隊列中,消費者可以從隊列中獲取消息並消費。

多個消費者可以訂閱同一個隊列,這時隊列中的消息會被平均分攤(Round-Robin,即輪詢)給多個消費者進行處理,而不是每個消費者都收到所有的消息並處理,這樣避免的消息被重複消費。

4. Broker(消息中間件的服務節點)

對於 RabbitMQ 來說,一個 RabbitMQ Broker 可以簡單地看作一個 RabbitMQ 服務節點,或者RabbitMQ服務實例。大多數情況下也可以將一個 RabbitMQ Broker 看作一臺 RabbitMQ 服務器。

下圖展示了生產者將消息存入 RabbitMQ Broker,以及消費者從Broker中消費數據的整個流程:

至此,RabbitMQ的概念就簡單介紹完了,RabbitMQ的安裝請參考我的另一篇博客 linux安裝rabbitMQ

 

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