Docker搭建RabbitMq的普通集群和鏡像集群的詳細操作

普通集群:多個節點組成的普通集群,消息隨機發送到其中一個節點的隊列上,其他節點僅保留元數據,各個節點僅有相同的元數據,即隊列結構、交換器結構、vhost等。消費者消費消息時,會從各個節點拉取消息,如果保存消息的節點故障,則無法消費消息,如果做瞭消息持久化,那麼得等該節點恢復,然後才可被消費;如果沒有持久化的話,就會產生消息丟失的現象。

鏡像集群:它是在普通模式的基礎上,把需要的隊列做成鏡像隊列,存在於多個節點來實現高可用(HA)。該模式解決瞭上述問題,Broker會主動地將消息實體在各鏡像節點間同步,在consumer取數據時無需臨時拉取。該模式帶來的副作用也很明顯,除瞭降低系統性能外,如果鏡像隊列數量過多,加之大量的消息進入,集群內部的網絡帶寬將會被大量消耗。通常地,對可靠性要求較高的場景建議采用鏡像模式。

一、搭建RabbitMq的運行環境

我本機是window10,通過docker搭建兩個rabbitmq節點。

1.通過search查詢rabbitmq鏡像

docker search rabbitmq

2.通過pull拉取rabbitmq的官方最新鏡像

這裡最好帶上tag為management的版本,否則拉最新的latest,web管理頁無法顯示全,會提示overview:management only mode

docker pull rabbitmq:3.8.25-management

3.創建容器

 docker run -d –name rabbitmq1 -p 5672:5672 -p 15672:15672 –hostname myRabbit1 -e RABBITMQ_DEFAULT_VHOST=my_vhost1  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin a4eb038c2ecb

–name:容器名稱

-p:端點映射

–hostname:rabbitmq的節點名稱

-e RABBITMQ_DEFAULT_VHOST:虛擬主機名稱

-e RABBITMQ_DEFAULT_USER:登錄賬號

-e RABBITMQ_DEFAULT_PASS:登錄密碼

a4eb038c2ecb是鏡像id,根據自己情況替換。

4.啟動管理頁面

我們的鏡像默認沒有開啟web管理頁面,所以我們通過exec命令進入容器啟動,這個鏡像的環境是ubuntu的

PS C:\> docker exec -it 639a151c5440 /bin/bash
root@myRabbit:/# rabbitmq-plugins enable rabbitmq_management

瀏覽器中訪問http://localhost:15672/即可打開,另一個rabbitmq如法炮制,區別之處在於更換端口為5673和15673等,並且創建容器時使用–link連接第一個rabbitmq節點(也可創建橋接網絡network連接),如下

docker run -d –name rabbitmq2 -p 5673:5672 -p 15673:15672 –hostname myRabbit2 -e RABBITMQ_DEFAULT_VHOST=my_vhost2  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin –link rabbitmq1:myRabbit1 a4eb038c2ecb

5.設置erlang cookie

erlang cookie原本可以通過run容器時設置參數-e RABBITMQ_ERLANG_COOKIE,但是現在過期棄用瞭。

我們先通過docker logs命令查看容器的運行日志,尋找home dir參數如下

PS D:\> docker logs rabbitmq1
//.....這裡省略
  Starting broker...2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  node           : rabbit@myRabbit1
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  home dir       : /var/lib/rabbitmq
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  config file(s) : /etc/rabbitmq/conf.d/10-default-guest-user.conf
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>                 : /etc/rabbitmq/conf.d/management_agent.disable_metrics_collector.conf
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  cookie hash    : Aed9pjd9vYWw3hng7Gjmkg==
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  log(s)         : /var/log/rabbitmq/rabbit@myRabbit1_upgrade.log
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>                 : <stdout>
2021-11-17 02:19:55.859245+00:00 [info] <0.222.0>  database dir   : /var/lib/rabbitmq/mnesia/rabbit@myRabbit1

所以.erlang.cookie文件在此路徑下,我們進入容器可以看到此文件

root@myRabbit1:~# ls -a /var/lib/rabbitmq
.  ..  .bash_history  .erlang.cookie  mnesia

我們再設置erlang cookie的權限,在容器內運行如下代碼,如果權限不夠後續操作會報錯

chmod 600 /var/lib/rabbitmq/.erlang.cookie

之後我們通過docker cp命令將rabbitmq1中的.erlang.cookie文件拷到物理機上再拷貝到rabbitmq2的容器中,物理機和容器之間復制命令如下:

  • 容器復制文件到物理機:docker cp 容器名稱:容器目錄
  • 物理機目錄物理機復制文件到容器:docker cp 物理機目錄 容器名稱:容器目錄

具體代碼如下:

docker cp rabbitmq1:/var/lib/rabbitmq/  d:\workspace\
docker cp d:\workspace\rabbitmq\.erlang.cookie rabbitmq2:/var/lib/rabbitmq/

復制之後需要重啟rabbitmq2容器,否則執行rabbitmqctl命令報如下錯誤:

[error] Cookie file /var/lib/rabbitmq/.erlang.cookie must be accessible by owner only

二、普通模式

重啟後進入容器將rabbitmq2的節點加入rabbitmq1中創建普通集群,分別執行如下代碼即可:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@myRabbit1    //myRabbitmq1為rabbitmq1容器中rabbitmq的hostname
rabbitmqctl start_app

之後我們再web管理頁可以看到兩個節點瞭。

在任意一個節點創建一個隊列,另一個節點也會生成相同的隊列。而且可以發現rabbitmq2的vhost從my_vhost2變為瞭my_vhost1與rabbitmq相同瞭。

三、鏡像模式

鏡像模式就是在普通模式的基礎上進入rabbitmq1容器輸入如下命令即可:

rabbitmqctl set_policy -p my_vhost1 ha-all “^” ‘{“ha-mode”:”all”}’ –apply-to all

具體的格式為

rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
-p Vhost: 可選參數,針對指定vhost下的queue進行設置
Name: policy的名稱
Pattern: queue的匹配模式(正則表達式)
Definition:鏡像定義,包括三個部分ha-mode, ha-params, ha-sync-mode
        ha-mode:指明鏡像隊列的模式,有效值為 all/exactly/nodes
            all:表示在集群中所有的節點上進行鏡像
            exactly:表示在指定個數的節點上進行鏡像,節點的個數由ha-params指定
            nodes:表示在指定的節點上進行鏡像,節點名稱通過ha-params指定
        ha-params:作為參數,為ha-mode的補充
        ha-sync-mode:進行隊列中消息的同步方式,有效值為automatic和manual
priority:可選參數,policy的優先級

rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' --apply-to all

或者登錄rabbitmq管理頁面 ——> Admin ——> Policies ——> Add / update a policy

name:策略名稱

Pattern:^ 匹配符,隻有一個^代表匹配所有。^message指同步“message”開頭的隊列名稱

Definition:ha-mode=all 為匹配類型,分為3種模式:all(表示所有的queue)

Priority:優先級,首先根據priority排序,值越大的優先級越高;相同priority則根據創建時間排序,越晚創建的優先級越高。

簡單說明一下 Operator Policy 和 User Policy 的區別:

  • Operator Policy 是給服務提供商或公司基礎設施部門用來設置某些需要強制執行的通用規則
  • User Policy 是給業務應用用來設置的規則

Operator Policy 和 User Policy 會合並後作用於隊列,並且為防止 Operator Policy 對隊列某些關鍵屬性例如死信隊列交換器Dead Letter Exchange的覆蓋導致業務應用產生非預期的結果,Operator Policy 隻支持expiremessage-ttlmax-lengthmax-length-bytes4個參數。

參考學習:

https://www.cnblogs.com/knowledgesea/p/6535766.html

https://blog.csdn.net/belonghuang157405/article/details/83540148

到此這篇關於Docker搭建RabbitMq的普通集群和鏡像集群的文章就介紹到這瞭,更多相關Docker搭建RabbitMq集群內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: