動力節(jié)點RabbitMQ教程|12小時學會rabbitmq消息中間件

1 RabbitMQ集群與高可用
RabbitMQ 的集群分兩種模式,一種是默認集群模式,一種是鏡像集群模式;
在RabbitMQ集群中所有的節(jié)點(一個節(jié)點就是一個RabbitMQ的broker服務器) 被歸為兩類:一類是磁盤節(jié)點,一類是內(nèi)存節(jié)點;
磁盤節(jié)點會把集群的所有信息(比如交換機、綁定、隊列等信息)持久化到磁盤中,而內(nèi)存節(jié)點只會將這些信息保存到內(nèi)存中,如果該節(jié)點宕機或重啟,內(nèi)存節(jié)點的數(shù)據(jù)會全部丟失,而磁盤節(jié)點的數(shù)據(jù)不會丟失;
1.1 默認集群模式
默認集群模式也叫 普通集群模式、或者 內(nèi)置集群模式;??
RabbitMQ默認集群模式,只會把交換機、隊列、虛擬主機等元數(shù)據(jù)信息在各個節(jié)點同步,而具體隊列中的消息內(nèi)容不會在各個節(jié)點中同步;

元數(shù)據(jù)
隊列元數(shù)據(jù):隊列名稱和屬性(是否可持久化,是否自動刪除)
交換器元數(shù)據(jù):交換器名稱、類型和屬性
綁定元數(shù)據(jù):交換器和隊列的綁定列表
vhost元數(shù)據(jù):vhost內(nèi)的相關(guān)屬性,如安全屬性等;
當用戶訪問其中任何一個RabbitMQ節(jié)點時,查詢到的queue/user/exchange/vhost等信息都是相同的;
但集群中隊列的具體信息數(shù)據(jù)只在隊列的擁有者節(jié)點保存,其他節(jié)點只知道隊列的元數(shù)據(jù)和指向該節(jié)點的指針,所以其他節(jié)點接收到不屬于該節(jié)點隊列的消息時會將該消息傳遞給該隊列的擁有者節(jié)點上;
為什么集群不復制隊列內(nèi)容和狀態(tài)到所有節(jié)點:
1)存儲空間;
2)性能;
如果消息需要復制到集群中每個節(jié)點,網(wǎng)絡開銷不可避免,持久化消息還需要寫磁盤,占用磁盤空間。
那么問題來了?
如果有一個消息生產(chǎn)者或者消息消費者通過amqp-client的客戶端連接到節(jié)點1進行消息的發(fā)送或接收,那么此時集群中的消息收發(fā)只與節(jié)點1相關(guān),這個沒有任何問題;
如果客戶端相連的是節(jié)點2或者節(jié)點3?(隊列1數(shù)據(jù)不在該節(jié)點上),那么情況又會是怎么樣呢?
如果消息生產(chǎn)者所連接的是節(jié)點2或者節(jié)點3,此時隊列1的完整數(shù)據(jù)不在該兩個節(jié)點上,那么在發(fā)送消息過程中這兩個節(jié)點主要起了一個路由轉(zhuǎn)發(fā)作用,根據(jù)這兩個節(jié)點上的元數(shù)據(jù)(也就是指向queue的owner node的指針)轉(zhuǎn)發(fā)至節(jié)點1上,最終發(fā)送的消息還是會存儲至節(jié)點1的隊列1上;
同樣,如果消息消費者所連接的節(jié)點2或者節(jié)點3,那這兩個節(jié)點也會作為路由節(jié)點起到轉(zhuǎn)發(fā)作用,將會從節(jié)點1的隊列1中獲取消息進行消費;
2 安裝前準備
2.1 從已經(jīng)安裝好rabbitmq的機器 clone 三臺機器
2.2 重新設置三臺機器的mac地址
注意clone完,先不要啟動三臺機器,三臺機器均要重新生成mac地址,防止clone出的機器ip地址重復



2.3 啟動三臺機器
啟動并查看三臺機器的ip地址:
ip a
?
2.4 使用xshell 連接三臺機器
2.5 修改三臺機器的/etc/hosts 文件
首先需要配置一下hosts文件,因為RabbitMQ集群節(jié)點名稱是讀取hosts文件得到的;
vim /etc/hosts
192.168.131.128 rabbit128
192.168.131.129?rabbit129
192.168.131.130?rabbit130
2.6 三臺機器均重啟網(wǎng)絡,使節(jié)點名生效
systemctl restart network
2.7 三臺機器的xshell均退出,然后再重新連接
2.8 三臺機器的防火墻處理
systemctl status firewalld
systemctl stop firewalld ?--關(guān)閉防火墻
systemctl disable firewalld ?--開機不啟動防火墻
2.9 三臺機器 .erlang.cookie文件保持一致
由于是clone出的三臺機器,所以肯定是一樣的
如果我們使用解壓縮方式安裝的RabbitMQ,那么該文件會在${用戶名}目錄下,也就是${用戶名}/.erlang.cookie;
如果我們使用rpm安裝包方式進行安裝,那么這個文件會在/var/lib/rabbitmq目錄下;
注意 .erlang.cookie的權(quán)限為400,目前已經(jīng)是400
3 分別啟動三臺機器上的rabbitmq
3.1 啟動
rabbitmq-server -detached
3.2 查看集群狀態(tài)
使用以下命令查看集群狀態(tài)
rabbitmqctl cluster_status
3.4 構(gòu)建集群
在rabbitmq129機器上執(zhí)行命令,讓129的rabbitmq加入集群:
./rabbitmqctl stop_app
./rabbitmqctl reset
?
./rabbitmqctl join_cluster rabbit@rabbit128 --ram
./rabbitmqctl start_app
?
--ram 參數(shù)表示讓rabbitmq129成為一個內(nèi)存節(jié)點,如果不帶參數(shù)默認為disk磁盤節(jié)點;
把rabbit129節(jié)點添加完之后;
在rabbit130節(jié)點上也執(zhí)行同樣的命令,使rabbit130節(jié)點也加入到集群中,
./rabbitmqctl stop_app
./rabbitmqctl reset
?
./rabbitmqctl join_cluster rabbit@rabbit128 --ram
./rabbitmqctl start_app
當然也可以讓rabbit130作為一個磁盤節(jié)點
3.5 操作一個節(jié)點,添加用戶和權(quán)限等
#列出用戶
rabbitmqctl list_users
# 添加用戶
rabbitmqctl add_user admin 123456
#查看權(quán)限
rabbitmqctl list_permissions
#設置權(quán)限
rabbitmqctl set_permissions admin ".*" ".*" ".*"
#設置角色
rabbitmqctl set_user_tags admin administrator
#啟動web控制臺插件
./rabbitmq-plugins enable rabbitmq_management?
?
使用web瀏覽器添加一個虛擬主機 :powernode
3.6 再次查看集群狀態(tài)
當執(zhí)行完操作以后我們在瀏覽器訪問web管控臺來看看效果;
隨便在哪個節(jié)點打開web管控臺都能看到集群環(huán)境各節(jié)點的信息;
也可以使用 ./rabbitmqctl cluster_status?查看集群狀態(tài);
3.7 一些原理
RabbitMQ底層是通過Erlang架構(gòu)來實現(xiàn)的,所以rabbitmqctl會啟動Erlang節(jié)點,并基于Erlang節(jié)點來使用Erlang系統(tǒng)連接RabbitMQ節(jié)點,在連接過程中需要正確的Erlang Cookie和節(jié)點名稱,Erlang節(jié)點通過交換Erlang Cookie以獲得認證;
?
以上就是RabbitMQ默認集群模式(普通集群模式)的搭建;
3.8 Springboot 連接集群
spring:
??#配置rabbitmq
??rabbitmq:
????# 連接集群,使用逗號分隔
????addresses: 192.168.150.150:5672,192.168.150.151:5672,192.168.150.152:5672
????username: admin
????password: 123456
????virtual-host: powernode
4 鏡像集群模式
鏡像模式是基于默認集群模式加上一定的配置得來的;
在默認模式下的RabbitMQ集群,它會把所有節(jié)點的交換機、綁定、隊列的元數(shù)據(jù)進行復制確保所有節(jié)點都有一份相同的元數(shù)據(jù)信息,但是隊列數(shù)據(jù)分為兩種:一種是隊列的元數(shù)據(jù)信息(比如隊列的最大容量,隊列的名稱等配置信息),另一種是隊列里面的消息;
鏡像模式,則是把所有的隊列數(shù)據(jù)完全同步,包括元數(shù)據(jù)信息和消息數(shù)據(jù)信息,當然這對性能肯定會有一定影響,當對數(shù)據(jù)可靠性要求較高時,可以使用鏡像模式;
實現(xiàn)鏡像模式也非常簡單,它是在普通集群模式基礎之上搭建而成的;
鏡像隊列配置命令:
./rabbitmqctl?set_policy?[-p Vhost] Name?Pattern Definition?[Priority]
-p Vhost: 可選參數(shù),針對指定vhost下的queue進行設置;
Name: policy的名稱;(可以自己取個名字就可以)
Pattern: queue的匹配模式(正則表達式);
Definition:鏡像定義,包括三個部分ha-mode, ha-params, ha-sync-mode;(json格式)
{“ha-mode”:”exactly”,”ha-params”:2}
???ha-mode:指明鏡像隊列的模式,有效值為 all/exactly/nodes
????????all:表示在集群中所有的節(jié)點上進行鏡像
????????exactly:表示在指定個數(shù)的節(jié)點上進行鏡像,節(jié)點的個數(shù)由ha-params指定
????????nodes:表示在指定的節(jié)點上進行鏡像,節(jié)點名稱通過ha-params指定
????ha-params:ha-mode模式需要用到的參數(shù)
????ha-sync-mode:進行隊列中消息的同步方式,有效值為automatic和manual
priority:可選參數(shù),policy的優(yōu)先級;
比如想配置所有名字開頭為policy_的隊列進行鏡像,鏡像數(shù)量為2,那么命令如下(在任意節(jié)點執(zhí)行如下命令):
./rabbitmqctl?set_policy?[-p Vhost] Name Pattern Definition?[Priority]
./rabbitmqctl set_policy?-p powernode ha_policy?"^policy_" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
?
如果要在所有節(jié)點所有隊列上進行鏡像,則(在任意節(jié)點執(zhí)行如下命令):
所有節(jié)點、所有虛擬主機、所有隊列 都進行鏡像
./rabbitmqctl?set_policy?[-p Vhost] Name Pattern Definition?[Priority]
./rabbitmqctl set_policy?ha-all?"^" '{"ha-mode":"all"}'?
針對某個虛擬主機進行鏡像
rabbitmqctl set_policy -p powernode ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
?
(在默認集群模式的基礎上,執(zhí)行上面這個命令就可以把一個默認的集群模式變成鏡像集群模式)
?