拜讀了網上很多前輩的文章,對RabbitMQ的集群有了一點點認識.
好多文章都說到,RabbitMQ的集群分為普通集群和鏡像集群,有的還加了兩種:單機集群和主從集群.
我看來看去,看了半天,怎么感覺,其實RabbitMQ的集群實際就一種:普通集群.
至於單機集群,無非是在一台機器上模擬普通集群,
鏡像集群,不過是RabbitMQ的HA方案而已,因為這種集群方式在部署的時候,其實是通過配置參數,讓隊列可以"真正的"在多個節點上存儲.(而普通集群,隊列實際只會存儲在一個節點).
主從集群,則是在鏡像集群的基礎上,加一層負載均衡而已.
個人愚見,也許不對.
一.原理
RabbitMQ的集群的設計目的是在增加更多節點時,能線性的增加性能(CPU,內存)和容量(內存,磁盤).同時,一個節點宕機了,其他節點依然可以提供 RabbitMQ 的服務.
所以,隊列的完整數據只會保存在創建它的那個節點上,其他節點只會保存該隊列的元數據和一個指向這個隊列的指針而已.
一個隊列的完整數據包括隊列的元數據和隊列的內容:
RabbitMQ一共有4種類型的元數據,並且,RabbitMQ集群會始終同步這4種元數據.
- 隊列元數據:隊列的名稱和聲明隊列時設置的屬性(是否持久化、是否自動刪除、隊列所屬的節點)
- 交換機元數據:交換機的名稱、類型、屬性(是否持久化等)
- 綁定元數據:一張簡單的表格展示了如何將消息路由到隊列.包含的列有 交換機名稱、交換機類型、路由鍵、隊列名稱等
- vhost元數據:為vhost內隊列、交換機和綁定提供命名空間和安全屬性
因此,當用戶訪問其中任何一個RabbitMQ節點時,通過rabbitmqctl查詢到的queue,user,exchange,vhost等信息都是相同的.
下圖是一個有3個節點的集群,可以看到,消息保存在節點1.
當消費者從節點2獲取消息時,RabbitMQ 會把節點1的消息取出來,傳遞到節點2,再發送給消費者.這種方式的最大問題在於,如果節點1宕機了,那么節點2和節點3就無法獲取到節點1中還未消費的消息了.
如果做了隊列持久化及消息持久化,那么必須等到節點1恢復后,才能被消費,並且在節點1恢復之前,其它節點不能再創建節點1已經創建過的隊列;
如果隊列沒有持久化,消息就會失丟.
因此,這種默認的集群模式更適合非持久化隊列,只有該隊列是非持久話的,客戶端才能重新連接到集群里的其他節點,並重新創建該隊列.假如該隊列是持久化的,那么只能將故障節點恢復起來.否則,永遠無法創建同名的隊列.
為了證明上面說的話,我們通過搭建一個單機集群,來模擬這個場景 .
二.搭建單機集群
1.配置Hosts節點
127.0.0.1 node1
127.0.0.1 node2
2.復制兩份 RabbitMQ ,分別取名"-1","-2"
這里我們約定 "-1" 是 node1 的 RabbitMQ,"-2"是 node2 的 RabbitMQ.
3.修改 node1 的 rabbitmq-env.bat 文件
文件路徑 : rabbitmq_server-3.7.10-1\sbin\rabbitmq-env.bat
在 16 行加如下配置:
set RABBITMQ_CONFIG_FILE=!RABBITMQ_HOME!\etc\rabbitmq-node1 set RABBITMQ_BASE=!RABBITMQ_BASE!\rabbitmq-cluster set RABBITMQ_NODENAME=rabbit1@node1 set RABBITMQ_NODE_PORT=5672
再上個圖,清楚些.
注意第19行, 是 rabbit1@node1 ,不是 rabbit@node1 ,單機集群,@前面一定要不一樣,否則會"痛不欲生"...
4.修改 node1 的 rabbitmq-node1.config 文件
首先進入 rabbitmq_server-3.7.10-1\etc 文件夾,安裝的時候會有一個官方示例文件 : rabbitmq.config.example
復制一份,改個名 : rabbitmq-node1.config
在 542 行加如下配置:
{listener,[{port,15672}, {ip,"127.0.0.1"}, {ssl,false}]}
注意,我的 RabbitMQ 版本是 3.7.10 ,版本不一樣,行數不一樣,截個圖,就是在這幾行注釋下面 :
5.啟動 node1
1)關閉啟動的 RabbitMQ
由於電腦上已經以window服務的方式啟動了RabbitMQ,為了方便演示單機集群的搭建,所以我們需要將它關閉掉.
rabbitmq-service stop
,
2)啟動 node 1 的 RabbitMQ
進入 node1 的 sbin 文件夾,也就是 rabbitmq_server-3.7.10-1\sbin 文件夾,然后我們以后台應用的方式啟動.
rabbitmq-server -detached
驗證一下:
在瀏覽器地址欄輸入 http://localhost:15672/#/
如果沒有啟動管理后台插件,需要先啟動它 : rabbitmq-plugins enable rabbitmq_management (由於之前已經啟動過了,所以我這里就不需要再啟動了)
默認的賬號密碼都是 guest
在管理后台可以看到,node1 已經成功啟動了.
6.修改 node2 的配置文件
按照第3,4步的方式修改,只是把管理后台的端口由 15672 改成 15673,當然,文件名要改成 rabbitmq-node2.config
{listener,[{port,15673}, {ip,"127.0.0.1"}, {ssl,false}]}
rabbitmq-env.bat 文件修改如下,紅色標注,特別注意 rabbit2@node2
set RABBITMQ_CONFIG_FILE=!RABBITMQ_HOME!\etc\rabbitmq-node2 set RABBITMQ_BASE=!RABBITMQ_BASE!\rabbitmq-cluster set RABBITMQ_NODENAME=rabbit2@node2 set RABBITMQ_NODE_PORT=5673
7.啟動 node2
參考第5步的第2小步啟動.
驗證一下:
在瀏覽器地址欄輸入 http://localhost:15673/#/
沒毛病!
8.將 node2 加入集群
1)關閉 node2
rabbitmqctl stop_app
2)將 node2 加入到 node1
rabbitmqctl join_cluster rabbit1@node1
3)啟動 node2
先停止 rabbitmqctl stop
在啟動 rabbitmq-server -detached
4)打開 15672 和 15673 管理后台驗證:
三.節點操作
增加
刪除
硬刪除
參考:
https://www.cnblogs.com/nulige/p/8874893.html
https://blog.csdn.net/vbirdbest/article/details/78723467
https://blog.csdn.net/fgf00/article/details/79558498