【Java】 一文搞懂 RabbitMQ 的重要概念以及安裝
目錄
1.2.1 Producer(生產者) 和 Consumer(消費者)
一 RabbitMQ 介紹
這部分參考了 《RabbitMQ實戰指南》這本書的第 1 章和第 2 章。
1.1 RabbitMQ 簡介
RabbitMQ 是採用 Erlang 語言實現 AMQP(Advanced Message Queuing Protocol,高階訊息佇列協議)的訊息中介軟體,它最初起源於金融系統,用於在分散式系統中儲存轉發訊息。
RabbitMQ 發展到今天,被越來越多的人認可,這和它在易用性、擴充套件性、可靠性和高可用性等方面的卓著表現是分不開的。RabbitMQ 的具體特點可以概括為以下幾點:
-
可靠性: 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 模型更像是一種交換機模型。
下面再來看看圖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中的交換器看作一個簡單的實體。
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型別的交換器就會無視,而是將訊息路由到所有繫結到該交換器的佇列中。
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 中。
以上圖為例,如果傳送訊息的時候設定路由鍵為“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 中可以存在兩種特殊字串“”和“#”,用於做模糊匹配,其中“”用於匹配一個單詞,“#”用於匹配多個單詞(可以是零個)。
以上圖為例:
-
路由鍵為 “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 的版本關係,如果不注意的話會導致出錯,兩者對應關係如下:
2.1 安裝 erlang
1 下載 erlang 安裝包
在官網下載然後上傳到 Linux 上或者直接使用下面的命令下載對應的版本。
[root@SnailClimb local]#wget http://erlang.org/download/otp_src_19.3.tar.gz
erlang 官網下載:Downloads - Erlang/OTP
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", []).
大功告成,我們的 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
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
或者直接在官網下載
Installing on RPM-based Linux | RabbitMQ
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 Centos7 安裝以及使用MQCentOS
- 1.RabbitMQ入門-概念、安裝、配置MQ
- 快速掌握RabbitMQ(一)——RabbitMQ的基本概念、安裝和C#驅動MQC#
- 【RabbitMQ】安裝MQ
- 安裝RabbitMQMQ
- 一文搞懂應用架構的3個核心概念應用架構
- 如何安裝RabbitMQMQ
- Windows RabbitMQ安裝WindowsMQ
- Docker安裝RabbitmqDockerMQ
- Mac 安裝 RabbitMQMacMQ
- docker 安裝 RabbitMQDockerMQ
- Ubantu 安裝 rabbitMQMQ
- mac安裝rabbitmqMacMQ
- centOS安裝rabbitMQCentOSMQ
- Ubuntu 安裝 RabbitMQUbuntuMQ
- Linux中如何安裝RabbitMQ?在linux系統中安裝Rabbitmq的方法LinuxMQ
- jdk安裝以及JAVA_HOME和CLASSPATH以及Path的含義JDKJava
- 一文搞懂 Java8 reduce操作Java
- 一文搞懂Java隨機數生成Java隨機
- Java 基礎 一文搞懂泛型Java泛型
- 掌握Rabbitmq幾個重要概念,從一條訊息說起MQ
- 夯實Java基礎系列19:一文搞懂Java集合類框架,以及常見面試題Java框架面試題
- Linux如何安裝RabbitMQLinuxMQ
- RabbitMQ安裝配置(CentOS)MQCentOS
- rabbitMq急速安裝教程MQ
- CentOS7安裝rabbitmqCentOSMQ
- Rabbitmq安裝與配置MQ
- Linux下安裝RabbitMQLinuxMQ
- centos 7 安裝 rabbitMqCentOSMQ
- Docker Compose 安裝 RabbitMQDockerMQ
- Java軟體安裝以及環境配置Java
- 【RabbitMQ】核心概念MQ
- 一文搞懂所有Java集合面試題Java面試題
- 在 windows下安裝rabbitmqWindowsMQ
- RabbitMQ簡介及安裝MQ
- centos7.8 安裝RabbitmqCentOSMQ
- Centos7安裝RabbitMQCentOSMQ
- RabbitMQ 安裝與介面管理MQ