RabbitMQ入門看這一篇就夠了

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=RabbitMQ 是採用 Erlang 語言實現 AMQP(Advanced Message Queuing Protocol,高級消息隊列協議)的消息中間件,它最初起源於金融系統,用於在分佈式系統中存儲轉發消息。html

一文搞懂 RabbitMQ 的重要概念以及安裝

一 RabbitMQ 介紹

這部分參考了 《RabbitMQ實戰指南》這本書的第 1 章和第 2 章。java

1.1 RabbitMQ 簡介

RabbitMQ 是採用 Erlang 語言實現 AMQP(Advanced Message Queuing Protocol,高級消息隊列協議)的消息中間件,它最初起源於金融系統,用於在分佈式系統中存儲轉發消息。c++

RabbitMQ 發展到今天,被愈來愈多的人承認,這和它在易用性、擴展性、可靠性和高可用性等方面的卓著表現是分不開的。RabbitMQ 的具體特色能夠歸納爲如下幾點:web

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

1.2 RabbitMQ 核心概念

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

下面再來看看圖1—— RabbitMQ 的總體模型架構。瀏覽器

圖1-RabbitMQ 的總體模型架構

下面我會一一介紹上圖中的一些概念。服務器

1.2.1 Producer(生產者) 和 Consumer(消費者)

  • Producer(生產者) :生產消息的一方(郵件投遞者)
  • Consumer(消費者) :消費消息的一方(郵件收件人)

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

1.2.2 Exchange(交換器)

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

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

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

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

Exchange(交換器) 示意圖

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

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

Binding(綁定) 示意圖:

Binding(綁定) 示意圖

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

1.2.3 Queue(消息隊列)

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

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

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

RabbitMQ 不支持隊列層面的廣播消費,若是有廣播消費的需求,須要在其上進行二次開發,這樣會很麻煩,不建議這樣作。

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

對於 RabbitMQ 來講,一個 RabbitMQ Broker 能夠簡單地看做一個 RabbitMQ 服務節點,或者RabbitMQ服務實例。大多數狀況下也能夠將一個 RabbitMQ Broker 看做一臺 RabbitMQ 服務器。

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

消息隊列的運轉過程

這樣圖1中的一些關於 RabbitMQ 的基本概念咱們就介紹完畢了,下面再來介紹一下 Exchange Types(交換器類型) 。

1.2.5 Exchange Types(交換器類型)

RabbitMQ 經常使用的 Exchange Type 有 fanout、direct、topic、headers 這四種(AMQP規範裏還提到兩種 Exchange Type,分別爲 system 與 自定義,這裏不予以描述)。

① fanout

fanout 類型的Exchange路由規則很是簡單,它會把全部發送到該Exchange的消息路由到全部與它綁定的Queue中,不須要作任何判斷操做,因此 fanout 類型是全部的交換機類型裏面速度最快的。fanout 類型經常使用來廣播消息。

② direct

direct 類型的Exchange路由規則也很簡單,它會把消息路由到那些 Bindingkey 與 RoutingKey 徹底匹配的 Queue 中。

direct 類型交換器

以上圖爲例,若是發送消息的時候設置路由鍵爲「warning」,那麼消息會路由到 Queue1 和 Queue2。若是在發送消息的時候設置路由鍵爲"Info」或者"debug」,消息只會路由到Queue2。若是以其餘的路由鍵發送消息,則消息不會路由到這兩個隊列中。

direct 類型經常使用在處理有優先級的任務,根據任務的優先級把消息發送到對應的隊列,這樣能夠指派更多的資源去處理高優先級的隊列。

③ topic

前面講到direct類型的交換器路由規則是徹底匹配 BindingKey 和 RoutingKey ,可是這種嚴格的匹配方式在不少狀況下不能知足實際業務的需求。topic類型的交換器在匹配規則上進行了擴展,它與 direct 類型的交換器類似,也是將消息路由到 BindingKey 和 RoutingKey 相匹配的隊列中,但這裏的匹配規則有些不一樣,它約定:

  • RoutingKey 爲一個點號「.」分隔的字符串(被點號「.」分隔開的每一段獨立的字符串稱爲一個單詞),如 「com.rabbitmq.client」、「java.util.concurrent」、「com.hidden.client」;
  • BindingKey 和 RoutingKey 同樣也是點號「.」分隔的字符串;
  • BindingKey 中能夠存在兩種特殊字符串「」和「#」,用於作模糊匹配,其中「」用於匹配一個單詞,「#」用於匹配多個單詞(能夠是零個)。

topic 類型交換器

以上圖爲例:

  • 路由鍵爲 「com.rabbitmq.client」 的消息會同時路由到 Queuel 和 Queue2;
  • 路由鍵爲 「com.hidden.client」 的消息只會路由到 Queue2 中;
  • 路由鍵爲 「com.hidden.demo」 的消息只會路由到 Queue2 中;
  • 路由鍵爲 「java.rabbitmq.demo」 的消息只會路由到Queuel中;
  • 路由鍵爲 「java.util.concurrent」 的消息將會被丟棄或者返回給生產者(須要設置 mandatory 參數),由於它沒有匹配任何路由鍵。
④ headers(不推薦)

headers 類型的交換器不依賴於路由鍵的匹配規則來路由消息,而是根據發送的消息內容中的 headers 屬性進行匹配。在綁定隊列和交換器時制定一組鍵值對,當發送消息到交換器時,RabbitMQ會獲取到該消息的 headers(也是一個鍵值對的形式)'對比其中的鍵值對是否徹底匹配隊列和交換器綁定時指定的鍵值對,若是徹底匹配則消息會路由到該隊列,不然不會路由到該隊列。headers 類型的交換器性能會不好,並且也不實用,基本上不會看到它的存在。

二 安裝 RabbitMq

經過 Docker 安裝很是方便,只須要幾條命令就行了,我這裏是只說一下常規安裝方法。

前面提到了 RabbitMQ 是由 Erlang語言編寫的,也正因如此,在安裝RabbitMQ 以前須要安裝 Erlang。

注意:在安裝 RabbitMQ 的時候須要注意 RabbitMQ 和 Erlang 的版本關係,若是不注意的話會致使出錯,二者對應關係以下:

RabbitMQ 和 Erlang 的版本關係

2.1 安裝 erlang

1 下載 erlang 安裝包

在官網下載而後上傳到 Linux 上或者直接使用下面的命令下載對應的版本。

[root@SnailClimb local]#wget http://erlang.org/download/otp_src_19.3.tar.gz

erlang 官網下載:http://www.erlang.org/downloads

2 解壓 erlang 安裝包

[root@SnailClimb local]#tar -xvzf otp_src_19.3.tar.gz

3 刪除 erlang 安裝包

[root@SnailClimb local]#rm -rf otp_src_19.3.tar.gz

4 安裝 erlang 的依賴工具

[root@SnailClimb local]#yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel

5 進入erlang 安裝包解壓文件對 erlang 進行安裝環境的配置

新建一個文件夾

[root@SnailClimb local]# mkdir erlang

對 erlang 進行安裝環境的配置

[root@SnailClimb otp_src_19.3]# 
./configure --prefix=/usr/local/erlang --without-javac

6 編譯安裝

[root@SnailClimb otp_src_19.3]# 
make && make install

7 驗證一下 erlang 是否安裝成功了

[root@SnailClimb otp_src_19.3]# ./bin/erl

運行下面的語句輸出「hello world」

 io:format("hello world~n", []).

輸出「hello world」

大功告成,咱們的 erlang 已經安裝完成。

8 配置 erlang 環境變量

[root@SnailClimb etc]# vim profile

追加下列環境變量到文件末尾

#erlang
ERL_HOME=/usr/local/erlang
PATH=$ERL_HOME/bin:$PATH
export ERL_HOME PATH

運行下列命令使配置文件profile生效

[root@SnailClimb etc]# source /etc/profile

輸入 erl 查看 erlang 環境變量是否配置正確

[root@SnailClimb etc]# erl

輸入 erl 查看 erlang 環境變量是否配置正確

2.2 安裝 RabbitMQ

1. 下載rpm

wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.8/rabbitmq-server-3.6.8-1.el7.noarch.rpm

或者直接在官網下載

https://www.rabbitmq.com/install-rpm.html

2. 安裝rpm

rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc

緊接着執行:

yum install rabbitmq-server-3.6.8-1.el7.noarch.rpm

中途須要你輸入"y"才能繼續安裝。

3 開啓 web 管理插件

rabbitmq-plugins enable rabbitmq_management

4 設置開機啓動

chkconfig rabbitmq-server on

4. 啓動服務

service rabbitmq-server start

5. 查看服務狀態

service rabbitmq-server status

6. 訪問 RabbitMQ 控制檯

瀏覽器訪問:http://你的ip地址:15672/

默認用戶名和密碼: guest/guest;可是須要注意的是:guestuest用戶只是被允許從localhost訪問。官網文檔描述以下:

「guest」 user can only connect via localhost

解決遠程訪問 RabbitMQ 遠程訪問密碼錯誤

新建用戶並受權

[root@SnailClimb rabbitmq]# rabbitmqctl add_user root root
Creating user "root" ...
[root@SnailClimb rabbitmq]# rabbitmqctl set_user_tags root administrator

Setting tags for user "root" to [administrator] ...
[root@SnailClimb rabbitmq]# 
[root@SnailClimb rabbitmq]# rabbitmqctl set_permissions -p / root ".*" ".*" ".*"
Setting permissions for user "root" in vhost "/" ...

再次訪問:http://你的ip地址:15672/ ,輸入用戶名和密碼:root root

RabbitMQ控制檯

相關文章
相關標籤/搜索