RabbitMQ部署指南
1.單機(jī)部署
我們?cè)贑entos7虛擬機(jī)中使用Docker來安裝。
1.1.下載鏡像
方式一:在線拉取
docker pull rabbitmq:3-management
方式二:從本地加載
在課前資料已經(jīng)提供了鏡像包:
上傳到虛擬機(jī)中后,使用命令加載鏡像即可:
docker load -i mq.tar
1.2.安裝MQ
執(zhí)行下面的命令來運(yùn)行MQ容器:
docker run \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq \
--hostname mq1 \
-p 15672:15672 \
-p 5672:5672 \
-d \
rabbitmq:3-management
2.集群部署
接下來,我們看看如何安裝RabbitMQ的集群。
2.1.集群分類
在RabbitMQ的官方文檔中,講述了兩種集群的配置方式:
- 普通模式:普通模式集群不進(jìn)行數(shù)據(jù)同步,每個(gè)MQ都有自己的隊(duì)列、數(shù)據(jù)信息(其它元數(shù)據(jù)信息如交換機(jī)等會(huì)同步)。例如我們有2個(gè)MQ:mq1,和mq2,如果你的消息在mq1,而你連接到了mq2,那么mq2會(huì)去mq1拉取消息,然后返回給你。如果mq1宕機(jī),消息就會(huì)丟失。
- 鏡像模式:與普通模式不同,隊(duì)列會(huì)在各個(gè)mq的鏡像節(jié)點(diǎn)之間同步,因此你連接到任何一個(gè)鏡像節(jié)點(diǎn),均可獲取到消息。而且如果一個(gè)節(jié)點(diǎn)宕機(jī),并不會(huì)導(dǎo)致數(shù)據(jù)丟失。不過,這種方式增加了數(shù)據(jù)同步的帶寬消耗。
我們先來看普通模式集群,我們的計(jì)劃部署3節(jié)點(diǎn)的mq集群:
主機(jī)名 | 控制臺(tái)端口 | amqp通信端口 |
---|---|---|
mq1 | 8081 —> 15672 | 8071 —> 5672 |
mq2 | 8082 —> 15672 | 8072 —> 5672 |
mq3 | 8083 —> 15672 | 8073 —> 5672 |
集群中的節(jié)點(diǎn)標(biāo)示默認(rèn)都是:rabbit@[hostname]
,因此以上三個(gè)節(jié)點(diǎn)的名稱分別為:
- rabbit@mq1
- rabbit@mq2
- rabbit@mq3
2.2.獲取cookie
RabbitMQ底層依賴于Erlang,而Erlang虛擬機(jī)就是一個(gè)面向分布式的語言,默認(rèn)就支持集群模式。集群模式中的每個(gè)RabbitMQ 節(jié)點(diǎn)使用 cookie 來確定它們是否被允許相互通信。
要使兩個(gè)節(jié)點(diǎn)能夠通信,它們必須具有相同的共享秘密,稱為Erlang cookie。cookie 只是一串最多 255 個(gè)字符的字母數(shù)字字符。
每個(gè)集群節(jié)點(diǎn)必須具有相同的 cookie。實(shí)例之間也需要它來相互通信。
我們先在之前啟動(dòng)的mq容器中獲取一個(gè)cookie值,作為集群的cookie。執(zhí)行下面的命令:
docker exec -it mq cat /var/lib/rabbitmq/.erlang.cookie
可以看到cookie值如下:
GIIKNSACLCUKKXCZEHQD
接下來,停止并刪除當(dāng)前的mq容器,我們重新搭建集群。
docker rm -f mq
2.3.準(zhǔn)備集群配置
在/tmp目錄新建一個(gè)配置文件 rabbitmq.conf:
cd /tmp
# 創(chuàng)建文件
touch rabbitmq.conf
文件內(nèi)容如下:
loopback_users.guest = false
listeners.tcp.default = 5672
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.1 = rabbit@mq1
cluster_formation.classic_config.nodes.2 = rabbit@mq2
cluster_formation.classic_config.nodes.3 = rabbit@mq3
再創(chuàng)建一個(gè)文件,記錄cookie
cd /tmp
# 創(chuàng)建cookie文件
touch .erlang.cookie
# 寫入cookie
echo "GIIKNSACLCUKKXCZEHQD" > .erlang.cookie
# 修改cookie文件的權(quán)限
chmod 600 .erlang.cookie
準(zhǔn)備三個(gè)目錄,mq1、mq2、mq3:
cd /tmp
# 創(chuàng)建目錄
mkdir mq1 mq2 mq3
然后拷貝rabbitmq.conf、cookie文件到mq1、mq2、mq3:
# 進(jìn)入/tmp
cd /tmp
# 拷貝
cp rabbitmq.conf mq1
cp rabbitmq.conf mq2
cp rabbitmq.conf mq3
cp .erlang.cookie mq1
cp .erlang.cookie mq2
cp .erlang.cookie mq3
2.4.啟動(dòng)集群
創(chuàng)建一個(gè)網(wǎng)絡(luò):
docker network create mq-net
docker volume create
運(yùn)行命令
docker run -d --net mq-net \
-v ${PWD}/mq1/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=guest \
-e RABBITMQ_DEFAULT_PASS=guest \
--name mq1 \
--hostname mq1 \
-p 8071:5672 \
-p 8081:15672 \
docker.io/rabbitmq:3.8-management
docker logs -f mq1 #查看日志
docker run -d --net mq-net \
-v ${PWD}/mq2/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=guest \
-e RABBITMQ_DEFAULT_PASS=guest \
--name mq2 \
--hostname mq2 \
-p 8072:5672 \
-p 8082:15672 \
docker.io/rabbitmq:3.8-management
docker run -d --net mq-net \
-v ${PWD}/mq3/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=guest \
-e RABBITMQ_DEFAULT_PASS=guest \
--name mq3 \
--hostname mq3 \
-p 8073:5672 \
-p 8083:15672 \
docker.io/rabbitmq:3.8-management
2.5.測(cè)試
在mq1這個(gè)節(jié)點(diǎn)上添加一個(gè)隊(duì)列:
如圖,在mq2和mq3兩個(gè)控制臺(tái)也都能看到:
2.5.1.數(shù)據(jù)共享測(cè)試
點(diǎn)擊這個(gè)隊(duì)列,進(jìn)入管理頁(yè)面:
然后利用控制臺(tái)發(fā)送一條消息到這個(gè)隊(duì)列:
結(jié)果在mq2、mq3上都能看到這條消息:
2.5.2.可用性測(cè)試
我們讓其中一臺(tái)節(jié)點(diǎn)mq1宕機(jī):
docker stop mq1
然后登錄mq2或mq3的控制臺(tái),發(fā)現(xiàn)simple.queue也不可用了:
說明數(shù)據(jù)并沒有拷貝到mq2和mq3。
3.鏡像模式
在剛剛的案例中,一旦創(chuàng)建隊(duì)列的主機(jī)宕機(jī),隊(duì)列就會(huì)不可用。不具備高可用能力。如果要解決這個(gè)問題,必須使用官方提供的鏡像集群方案。
官方文檔地址:https://www.rabbitmq.com/ha.html
3.1.鏡像模式的特征
默認(rèn)情況下,隊(duì)列只保存在創(chuàng)建該隊(duì)列的節(jié)點(diǎn)上。而鏡像模式下,創(chuàng)建隊(duì)列的節(jié)點(diǎn)被稱為該隊(duì)列的主節(jié)點(diǎn),隊(duì)列還會(huì)拷貝到集群中的其它節(jié)點(diǎn),也叫做該隊(duì)列的鏡像節(jié)點(diǎn)。
但是,不同隊(duì)列可以在集群中的任意節(jié)點(diǎn)上創(chuàng)建,因此不同隊(duì)列的主節(jié)點(diǎn)可以不同。甚至,一個(gè)隊(duì)列的主節(jié)點(diǎn)可能是另一個(gè)隊(duì)列的鏡像節(jié)點(diǎn)。
用戶發(fā)送給隊(duì)列的一切請(qǐng)求,例如發(fā)送消息、消息回執(zhí)默認(rèn)都會(huì)在主節(jié)點(diǎn)完成,如果是從節(jié)點(diǎn)接收到請(qǐng)求,也會(huì)路由到主節(jié)點(diǎn)去完成。鏡像節(jié)點(diǎn)僅僅起到備份數(shù)據(jù)作用。
當(dāng)主節(jié)點(diǎn)接收到消費(fèi)者的ACK時(shí),所有鏡像都會(huì)刪除節(jié)點(diǎn)中的數(shù)據(jù)。
總結(jié)如下:
- 鏡像隊(duì)列結(jié)構(gòu)是一主多從(從就是鏡像)
- 所有操作都是主節(jié)點(diǎn)完成,然后同步給鏡像節(jié)點(diǎn)
- 主宕機(jī)后,鏡像節(jié)點(diǎn)會(huì)替代成新的主(如果在主從同步完成前,主就已經(jīng)宕機(jī),可能出現(xiàn)數(shù)據(jù)丟失)
- 不具備負(fù)載均衡功能,因?yàn)樗胁僮鞫紩?huì)有主節(jié)點(diǎn)完成(但是不同隊(duì)列,其主節(jié)點(diǎn)可以不同,可以利用這個(gè)提高吞吐量)
3.2.鏡像模式的配置
鏡像模式的配置有3種模式:
ha-mode | ha-params | 效果 |
---|---|---|
準(zhǔn)確模式exactly | 隊(duì)列的副本量count | 集群中隊(duì)列副本(主服務(wù)器和鏡像服務(wù)器之和)的數(shù)量。count如果為1意味著單個(gè)副本:即隊(duì)列主節(jié)點(diǎn)。count值為2表示2個(gè)副本:1個(gè)隊(duì)列主和1個(gè)隊(duì)列鏡像。換句話說:count = 鏡像數(shù)量 + 1。如果群集中的節(jié)點(diǎn)數(shù)少于count,則該隊(duì)列將鏡像到所有節(jié)點(diǎn)。如果有集群總數(shù)大于count+1,并且包含鏡像的節(jié)點(diǎn)出現(xiàn)故障,則將在另一個(gè)節(jié)點(diǎn)上創(chuàng)建一個(gè)新的鏡像。 |
all | (none) | 隊(duì)列在群集中的所有節(jié)點(diǎn)之間進(jìn)行鏡像。隊(duì)列將鏡像到任何新加入的節(jié)點(diǎn)。鏡像到所有節(jié)點(diǎn)將對(duì)所有群集節(jié)點(diǎn)施加額外的壓力,包括網(wǎng)絡(luò)I / O,磁盤I / O和磁盤空間使用情況。推薦使用exactly,設(shè)置副本數(shù)為(N / 2 +1)。 |
nodes | node names | 指定隊(duì)列創(chuàng)建到哪些節(jié)點(diǎn),如果指定的節(jié)點(diǎn)全部不存在,則會(huì)出現(xiàn)異常。如果指定的節(jié)點(diǎn)在集群中存在,但是暫時(shí)不可用,會(huì)創(chuàng)建節(jié)點(diǎn)到當(dāng)前客戶端連接到的節(jié)點(diǎn)。 |
這里我們以rabbitmqctl命令作為案例來講解配置語法。
語法示例:
3.2.1.exactly模式
rabbitmqctl set_policy ha-two "^two\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
-
rabbitmqctl set_policy
:固定寫法 -
ha-two
:策略名稱,自定義 -
"^two\."
:匹配隊(duì)列的正則表達(dá)式,符合命名規(guī)則的隊(duì)列才生效,這里是任何以two.
開頭的隊(duì)列名稱 -
'{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
: 策略內(nèi)容-
"ha-mode":"exactly"
:策略模式,此處是exactly模式,指定副本數(shù)量 -
"ha-params":2
:策略參數(shù),這里是2,就是副本數(shù)量為2,1主1鏡像 -
"ha-sync-mode":"automatic"
:同步策略,默認(rèn)是manual,即新加入的鏡像節(jié)點(diǎn)不會(huì)同步舊的消息。如果設(shè)置為automatic,則新加入的鏡像節(jié)點(diǎn)會(huì)把主節(jié)點(diǎn)中所有消息都同步,會(huì)帶來額外的網(wǎng)絡(luò)開銷
-
3.2.2.all模式
rabbitmqctl set_policy ha-all "^all\." '{"ha-mode":"all"}'
-
ha-all
:策略名稱,自定義 -
"^all\."
:匹配所有以all.
開頭的隊(duì)列名 -
'{"ha-mode":"all"}'
:策略內(nèi)容-
"ha-mode":"all"
:策略模式,此處是all模式,即所有節(jié)點(diǎn)都會(huì)稱為鏡像節(jié)點(diǎn)
-
3.2.3.nodes模式
rabbitmqctl set_policy ha-nodes "^nodes\." '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'
-
rabbitmqctl set_policy
:固定寫法 -
ha-nodes
:策略名稱,自定義 -
"^nodes\."
:匹配隊(duì)列的正則表達(dá)式,符合命名規(guī)則的隊(duì)列才生效,這里是任何以nodes.
開頭的隊(duì)列名稱 -
'{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'
: 策略內(nèi)容-
"ha-mode":"nodes"
:策略模式,此處是nodes模式 -
"ha-params":["rabbit@mq1", "rabbit@mq2"]
:策略參數(shù),這里指定副本所在節(jié)點(diǎn)名稱
-
3.3.測(cè)試
我們使用exactly模式的鏡像,因?yàn)榧汗?jié)點(diǎn)數(shù)量為3,因此鏡像數(shù)量就設(shè)置為2.
運(yùn)行下面的命令:
docker exec -it mq1 rabbitmqctl set_policy ha-two "^two\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
下面,我們創(chuàng)建一個(gè)新的隊(duì)列:
在任意一個(gè)mq控制臺(tái)查看隊(duì)列:
3.3.1.測(cè)試數(shù)據(jù)共享
給two.queue發(fā)送一條消息:
然后在mq1、mq2、mq3的任意控制臺(tái)查看消息:
3.3.2.測(cè)試高可用
現(xiàn)在,我們讓two.queue的主節(jié)點(diǎn)mq1宕機(jī):
docker stop mq1
查看集群狀態(tài):
查看隊(duì)列狀態(tài):
發(fā)現(xiàn)依然是健康的!并且其主節(jié)點(diǎn)切換到了rabbit@mq2上
4.仲裁隊(duì)列
從RabbitMQ 3.8版本開始,引入了新的仲裁隊(duì)列,他具備與鏡像隊(duì)里類似的功能,但使用更加方便。
4.1.添加仲裁隊(duì)列
在任意控制臺(tái)添加一個(gè)隊(duì)列,一定要選擇隊(duì)列類型為Quorum類型。
在任意控制臺(tái)查看隊(duì)列:
可以看到,仲裁隊(duì)列的 + 2字樣。代表這個(gè)隊(duì)列有2個(gè)鏡像節(jié)點(diǎn)。
因?yàn)橹俨藐?duì)列默認(rèn)的鏡像數(shù)為5。如果你的集群有7個(gè)節(jié)點(diǎn),那么鏡像數(shù)肯定是5;而我們集群只有3個(gè)節(jié)點(diǎn),因此鏡像數(shù)量就是3.
4.2.測(cè)試
可以參考對(duì)鏡像集群的測(cè)試,效果是一樣的。
4.3.集群擴(kuò)容
4.3.1.加入集群
1)啟動(dòng)一個(gè)新的MQ容器:
docker run -d --net mq-net \
-v ${PWD}/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
--name mq4 \
--hostname mq5 \
-p 8074:15672 \
-p 8084:15672 \
rabbitmq:3.8-management
2)進(jìn)入容器控制臺(tái):
docker exec -it mq4 bash
3)停止mq進(jìn)程
rabbitmqctl stop_app
4)重置RabbitMQ中的數(shù)據(jù):
rabbitmqctl reset
5)加入mq1:
rabbitmqctl join_cluster rabbit@mq1
6)再次啟動(dòng)mq進(jìn)程
rabbitmqctl start_app
4.3.2.增加仲裁隊(duì)列副本
我們先查看下quorum.queue這個(gè)隊(duì)列目前的副本情況,進(jìn)入mq1容器:
docker exec -it mq1 bash
執(zhí)行命令:
rabbitmq-queues quorum_status "quorum.queue"
結(jié)果:
現(xiàn)在,我們讓mq4也加入進(jìn)來:
rabbitmq-queues add_member "quorum.queue" "rabbit@mq4"
結(jié)果:
再次查看:
rabbitmq-queues quorum_status "quorum.queue"
查看控制臺(tái),發(fā)現(xiàn)quorum.queue的鏡像數(shù)量也從原來的 +2 變成了 +3:文章來源:http://www.zghlxwxcb.cn/news/detail-596399.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-596399.html
到了這里,關(guān)于Docker高級(jí)——Docker部署RabbitMQ(單機(jī),集群,仲裁隊(duì)列)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!