一、序言
RabbitMQ目前在開發中被廣泛應用,這篇文章用儘可能淺顯的語言來解釋RabbitMQ的入門知識,希望能夠幫助更多的人花費更好的時間入門。
如果你想更深入的瞭解RabbitMQ,可以繼續關注本頭條號後續發佈的文章或者自己從網上搜尋了資料,自己探索研究。
二、RabbitMQ是什麼
是傳輸服務,消費者(consumer)訂閱某個隊列。生產者(producer)創建消息,然後發佈到隊列(queue)中,最後將消息發送到監聽的消費者。
三、RabbitMQ具有的特點
1.可靠性(Reliability)
RabbitMQ 使用一些機制來保證可靠性,如持久化、傳輸確認、發佈確認。
2.靈活的路由(Flexible Routing)
在消息進入隊列之前,通過 Exchange 來路由消息的。對於典型的路由功能,RabbitMQ 已經提供了一些內置的 Exchange 來實現。針對更復雜的路由功能,可以將多個 Exchange 綁定在一起,也通過插件機制實現自己的 Exchange 。
3.消息集羣(Clustering)
多個 RabbitMQ 服務器可以組成一個集羣,形成一個邏輯 Broker 。
4.高可用(Highly Available Queues)
隊列可以在集羣中的機器上進行鏡像,使得在部分節點出問題的情況下隊列仍然可用。
5.多種協議(Multi-protocol)
RabbitMQ 支持多種消息隊列協議,比如 STOMP、MQTT 等等。
6.多語言客戶端(Many Clients)
RabbitMQ 幾乎支持所有常用語言,比如 Java、.NET、Ruby 等等。
7.管理界面(Management UI)
RabbitMQ 提供了一個易用的用戶界面,使得用戶可以監控和管理消息 Broker 的許多方面。
8.跟蹤機制(Tracing)
如果消息異常,RabbitMQ 提供了消息跟蹤機制,使用者可以找出發生了什麼。
9.插件機制(Plugin System)
RabbitMQ 提供了許多插件,來從多方面進行擴展,也可以編寫自己的插件。
四、RabbitMQ 基本概念
1.Message
消息,消息是不具名的,它由消息頭和消息體組成。消息體是不透明的,而消息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(相對於其他消息的優先權)、delivery-mode(指出該消息可能需要持久性存儲)等。
2.Publisher
消息的生產者,也是一個向交換器發佈消息的客戶端應用程序。
3.Exchange
交換器,用來接收生產者發送的消息並將這些消息路由給服務器中的隊列。
4.Binding
綁定,用於消息隊列和交換器之間的關聯。一個綁定就是基於路由鍵將交換器和消息隊列連接起來的路由規則,所以可以將交換器理解成一個由綁定構成的路由表。
5.Queue
消息隊列,用來保存消息直到發送給消費者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列裏面,等待消費者連接到這個隊列將其取走。
6.Connection
網絡連接,比如一個TCP連接。
7.Channel
信道,多路複用連接中的一條獨立的雙向數據流通道。信道是建立在真實的TCP連接內地虛擬連接,AMQP 命令都是通過信道發出去的,不管是發佈消息、訂閱隊列還是接收消息,這些動作都是通過信道完成。因爲對於操作系統來說建立和銷燬 TCP 都是非常昂貴的開銷,所以引入了信道的概念,以複用一條 TCP 連接。
8.Consumer
消息的消費者,表示一個從消息隊列中取得消息的客戶端應用程序。
9.Virtual Host
虛擬主機,表示一批交換器、消息隊列和相關對象。虛擬主機是共享相同的身份認證和加密環境的獨立服務器域。每個 vhost 本質上就是一個 mini 版的 RabbitMQ 服務器,擁有自己的隊列、交換器、綁定和權限機制。vhost 是 AMQP 概念的基礎,必須在連接時指定,RabbitMQ 默認的 vhost 是 / 。
10.Broker
表示消息隊列服務器實體。
五、AMQP 中的消息路由方式
1.direct
Exchange分發消息時根據類型的不同分發策略有區別,目前共四種類型:direct、fanout、topic、headers 。headers 匹配 AMQP 消息的 header 而不是路由鍵,此外 headers 交換器和 direct 交換器完全一致,但性能差很多,目前幾乎用不到了,所以直接看另外三種類型:
消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致, 交換器就將消息發到對應的隊列中。它是完全匹配、單播的模式。
2.fanout
每個發到 fanout 類型交換器的消息都會分到所有綁定的隊列上去。fanout交換器不處理路由鍵,只是簡單的將隊列綁定到交換器上,每個發送到交換器的消息都會被轉發到與該交換器綁定的所有隊列上。
3.topic
通過模式匹配分配消息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時隊列需要綁定到一個模式上。它將路由鍵和綁定鍵的字符串切分成單詞,這些單詞之間用點隔開。它同樣也會識別兩個通配符:符號“#”和符號“”。#匹配0個或多個單詞,匹配不多不少一個單詞。
六、RabbitMQ 集羣
RabbitMQ 最優秀的功能之一就是內建集羣,這個功能設計的目的是允許消費者和生產者在節點崩潰的情況下繼續運行,以及通過添加更多的節點來線性擴展消息通信吞吐量。
RabbitMQ 會始終記錄以下四種類型的內部元數據:
1.隊列元數據
包括隊列名稱和它們的屬性,比如是否可持久化,是否自動刪除
2.交換器元數據
交換器名稱、類型、屬性
3.綁定元數據
內部是一張表格記錄如何將消息路由到隊列
4.vhost 元數據
爲 vhost 內部的隊列、交換器、綁定提供命名空間和安全屬性
在集羣模式下提供兩種選擇:存到硬盤上(獨立節點的默認設置),存在內存中。內存節點可以提供出色的性能,磁盤節點能保障配置信息在節點重啓後仍然可用,那集羣中如何平衡這兩者呢?
RabbitMQ只要求集羣中至少有一個磁盤節點,所有其他節點可以是內存節點,當節點加入火離開集羣時,它們必須要將該變更通知到至少一個磁盤節點。集羣中的唯一磁盤節點崩潰的話,集羣仍然可以運行,但直到該節點恢復,否則無法更改任何東西。
RabbitMQ 集羣中可以共享 user、vhost、exchange等,所有的數據和狀態都是必須在所有節點上覆制的,除了消息隊列。RabbitMQ 節點可以動態的加入到集羣中。當在集羣中聲明隊列、交換器、綁定的時候,這些操作會直到所有集羣節點都成功提交元數據變更後才返回。
如果在集羣中創建隊列,集羣只會在單個節點而不是所有節點上創建完整的隊列信息。如果在集羣中創建隊列,集羣只會在單個節點而不是所有節點上創建完整的隊列信息。但是隊列的內容不會消失,在集羣的其他節點都有隊列鏡像。