部署rabbitMQ映象叢集實戰測試

PassZhang 發表於 2020-06-29

部署rabbitMQ映象叢集

版本資訊

rabbit MQ: 3.8.5
Erlang: 官方建議最低21.3 推薦22.x
         這裡用的是23

環境準備

主機規劃

主機 節點
172.16.14.3 磁碟節點
172.16.14.4 記憶體節點
172.16.14.5 磁碟節點
記憶體節點:
    記憶體節點將所有的佇列、交換機、繫結、使用者、許可權和 vhost 的後設資料定義儲存在記憶體中,好處是可以使得像交換機和佇列宣告等操作更加的快速。例外情況是:持久的 queue 的內容將被儲存到磁碟。

磁碟節點:
    將後設資料儲存在磁碟中,單節點系統只允許磁碟型別的節點,防止重啟 RabbitMQ 的時候,丟失系統的配置資訊。


注意點:
    1、記憶體節點由於不進行磁碟讀寫,它的效能比磁碟節點高。
    2、叢集中可以存在多個磁碟節點,磁碟節點越多整個叢集可用性越好,但是叢集整體效能不會線性增加,需要權衡考慮。
    3、RabbitMQ 要求在叢集中至少有一個磁碟節點,所有其他節點可以是記憶體節點,當節點加入或者離開叢集時,必須要將該變更通知到至少一個磁碟節點。如果叢集中唯一的一個磁碟節點崩潰的話,叢集仍然可以保持執行,但是無法進行其他操作(增刪改查),直到節點恢復。
    4、設定兩個磁碟節點,至少有一個是可用的,可以儲存後設資料的更改。

下載離線包

官網安裝手冊(https://www.rabbitmq.com/install-generic-unix.html)

rabbit MQ:二進位制版
➜  wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.5/rabbitmq-server-generic-unix-3.8.5.tar.xz

Erlang: 無依賴版 -- 該軟體包剝離了一些Erlang模組和依賴項,這些對執行RabbitMQ而言不是必需的。
➜  wget https://github.com/rabbitmq/erlang-rpm/releases/download/v22.2.8/erlang-22.2.8-1.el7.x86_64.rpm

安裝離線包

# 安裝erlang
yum install -y yum install erlang-22.2.8-1.el7.x86_64.rpm 

# 解壓rabbitmq
xz -d rabbitmq-server-generic-unix-3.8.5.tar.xz 
tar -xvf rabbitmq-server-generic-unix-3.8.5.tar -C /opt

hosts檔案

172.16.14.3    MQ1
172.16.14.4    MQ2
172.16.14.5    MQ3

配置檔案

我們要自己在$Home/etc/rabbitmq中建立rabbitmq-env.conf, 詳細資訊請參閱 官方配置說明

# 建立持久化目錄
mkdir -p /data/rabbitmq/store
mkdir -p /data/rabbitmq/logs 

# 建立配置檔案
vim /opt/rabbitmq_server-3.8.5/etc/rabbitmq/rabbitmq-env.conf
# 指定節點的名字,預設[email protected]${hostname} 
[email protected] 
# 指定埠,預設5672 
NODE_PORT=5672 
# 配置持久目錄 
MNESIA_BASE=/ahdata/rabbitmq/store
# 配置日誌目錄 預設檔名字:${NODENAME}.log 可以用配置修改 
LOG_BASE=/ahdata/rabbitmq/logs

啟用服務

常用命令

sbin/rabbitmq-server                          # 啟動server 
sbin/rabbitmq-server -detached                # 後臺啟動server 
sbin/rabbitmqctl status                       # 檢視節點狀態 
sbin/rabbitmqctl shutdown                     # 停止執行的節點 
sbin/rabbitmqctl stop_app                     # 停止mq服務
sbin/rabbitmqctl start_app                    # 啟動mq服務
sbin/rabbitmqctl cluster_status               # 檢視叢集狀態 
sbin/rabbitmqctl set_cluster_name [email protected]  # 修改叢集名稱 
sbin/rabbitmqctl join_cluster <cluster_name>  # 加入叢集 
sbin/rabbitmqctl change_cluster_node_type --node <node_name> [ disk | ram ]  # 修改節點型別

啟動rabbit

cd /opt/rabbitmq_server-3.8.5/ 
sbin/rabbitmq-server -detached   # 在後臺啟動應用
sbin/rabbitmqctl status          # 檢視節點狀態 

erlang.cookie

Erlang 節點間通過認證 Erlang cookie 的方式允許互相通訊。因為 rabbitmqctl 使用 Erlang OTP 通訊機制來和 Rabbit 節點通訊,執行 rabbitmqctl 的機器和所要連線的 Rabbit 節點必須使用相同的 Erlang cookie 。否則你會得到一個錯誤。

cat /root/.erlang.cookie 
IJPCAHDPWVYSDERZDUPG # 保持cookie一致

scp /root/.erlang.cookie       n218:/root/.erlang.cookie # 拷貝過去之後需要重啟一下mq服務
sbin/rabbitmqctl shutdown                     # 停止執行的節點 
sbin/rabbitmq-server -detached                # 在後臺啟動應用


scp /root/.erlang.cookie       n219:/root/.erlang.cookie # 拷貝過去之後需要重啟一下mq服務
sbin/rabbitmqctl shutdown                     # 停止執行的節點 
sbin/rabbitmq-server -detached                # 在後臺啟動應用

現在三臺機器上具有相同的 Erlang cookie 了。下面開始組建叢集。

叢集

基礎概念

RabbitMQ 叢集分為兩種:

  • 普通叢集
  • 映象叢集(普通叢集的升級)

普通叢集:

以兩個節點(rabbit01、rabbit02)為例來進行說明。
rabbit01和rabbit02兩個節點僅有相同的後設資料,即佇列的結構,但訊息實體只存在於其中一個節點rabbit01(或者rabbit02)中。

當訊息進入rabbit01節點的Queue後,consumer從rabbit02節點消費時,RabbitMQ會臨時在rabbit01、rabbit02間進行訊息傳輸,把A中的訊息實體取出並經過B傳送給consumer。

所以consumer應儘量連線每一個節點,從中取訊息。即對於同一個邏輯佇列,要在多個節點建立物理Queue。否則無論consumer連rabbit01或rabbit02,出口總在rabbit01,會產生瓶頸。當rabbit01節點故障後,rabbit02節點無法取到rabbit01節點中還未消費的訊息實體。

如果做了訊息持久化,那麼得等rabbit01節點恢復,然後才可被消費;如果沒有持久化的話,就會產生訊息丟失的現象。

映象叢集:

在普通叢集的基礎上,把需要的佇列做成映象佇列,訊息實體會主動在映象節點間同步,而不是在客戶端取資料時臨時拉取,也就是說多少節點訊息就會備份多少份。

該模式帶來的副作用也很明顯,除了降低系統效能外,如果映象佇列數量過多,加之大量的訊息進入,叢集內部的網路頻寬將會被這種同步通訊大大消耗掉。

所以在對可靠性要求較高的場合中適用。由於映象佇列之間訊息自動同步,且內部有選舉master機制,即使master節點當機也不會影響整個叢集的使用,達到去中心化的目的,從而有效的防止訊息丟失及服務不可用等問題。

普通叢集

叢集名

將叢集名修改為[email protected]

# 修改叢集名 
sbin/rabbitmqctl set_cluster_name [email protected] 
Setting cluster name to [email protected] ... 

# 檢視叢集狀態 
sbin/rabbitmqctl cluster_status   
Cluster status of node 
[email protected] ... 

Basics Cluster name: 
[email protected] 

Disk Nodes 
[email protected] 

Running Nodes 
[email protected]

加入叢集

在218、219節點上執行

sbin/rabbitmqctl stop_app 
sbin/rabbitmqctl join_cluster [email protected] 
sbin/rabbitmqctl start_app

修改節點型別

檢視叢集狀態

sbin/rabbitmqctl cluster_status 
Cluster status of node 
[email protected] ... 

Basics Cluster name: 
[email protected]

Disk Nodes    # 磁碟節點現在3個都是 
[email protected]    # 我們看到所有的節點都是disk型別與我們預設的架構不符 
[email protected]    # 我們需要修改一下這個架構 
[email protected] 

Running Nodes 
[email protected] 
[email protected] 
[email protected]

更改218節點為記憶體節點

# 停止節點 
sbin/rabbitmqctl stop_app 
# 與叢集通訊,從叢集中刪除節點 
sbin/rabbitmqctl reset 
# 以RAM模式重新加入叢集 
sbin/rabbitmqctl join_cluster [email protected] --ram 
# 啟動節點 
sbin/rabbitmqctl start_app 
sbin/rabbitmqctl cluster_status 
Cluster status of node [email protected] ... 
Basics Cluster name: 
[email protected]

Disk Nodes 
[email protected] 
[email protected] 

RAM Nodes 
[email protected] 

Running Nodes 
[email protected] 
[email protected] 
[email protected]

節點單機狀態時,reset 命令將清空節點的狀態,並將其恢復到空白狀態。當節點是叢集的一部分時,該命令也會和叢集中的磁碟節點通訊,告訴他們該節點正在離開叢集。

這很重要,不然,叢集會認為該節點出了故障,並期望其最終能夠恢復回來,在該節點回來之前,叢集禁止新的節點加入。

映象叢集(HA)

上面我們已經成功部署了一個普通叢集,普通叢集並不是高可用的,下面基於普通叢集升級為映象叢集 官方HA方案

sbin/rabbitmqctl set_policy <name> [-p <vhost>] <pattern> <definition> [--apply-to <apply-to>]    
name: 策略名稱    
vhost: 指定vhost, 預設值 /    
pattern: 通過正規表示式匹配哪些需要映象, ^為所有    
definition:         
ha-mode: 指明映象佇列的模式,有效值為 all/exactly/nodes
	all     表示在叢集所有的節點上進行映象,無需設定ha-params            
	exactly 表示在指定個數的節點上進行映象,節點的個數由ha-params指定             
	nodes   表示在指定的節點上進行映象,節點名稱通過ha-params指定
ha-params: 
ha-mode 模式需要用到的引數         
ha-sync-mode: 映象佇列中訊息的同步方式,有效值為automatic,manually    
apply-to: 策略作用物件。可選值3個,預設all        
	exchanges 表示映象 exchange (並不知道意義所在)        
	queues    表示映象 queue        all       
	表示映象 exchange和queue ➜  

# 示例命令
sbin/rabbitmqctl set_policy admin "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
ha-mode ha-params 功能
all 映象佇列將會在整個叢集中複製。當一個新的節點加入後,也會在這 個節點上覆制一份。
exactly count 映象佇列將會在叢集上覆制 count 份。如果叢集數量少於 count 時候,佇列會複製到所有節點上。如果大於 Count 叢集,有一個節點 crash 後,新進入節點也不會做新的映象。
nodes node name 映象佇列會在 node name 中複製。如果這個名稱不是叢集中的一個,這不會觸發錯誤。如果在這個 node list 中沒有一個節點線上,那麼這個 queue 會被宣告在 client 連線的節點。

WEB管理

啟用WEB管理外掛

# 啟動web管理外掛 
sbin/rabbitmq-plugins enable rabbitmq_management 

# 增加使用者 
sbin/rabbitmqctl add_user admin admin 

# 配置使用者許可權
sbin/rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
示例:我們賦予 admin 在“/”下面的全部資源的配置和讀寫許可權。注意”/”代表 virtual host 為“/”這個“/”和 Linux 裡的根目錄是有區別的並不是 virtual host 為“/”可以訪問所以的 virtual host,把這個“/”理解成字串就行。

# 設定使用者角色 
sbin/rabbitmqctl set_user_tags admin administrator

訪問管理介面

開啟瀏覽器訪問 http://nodeip:15672, 使用上面建立的使用者登入即可

ss -tnlp | grep 5672 LISTEN     0      128          *:25672                    *:*                   users:(("beam.smp",pid=3593,fd=77)) LISTEN     0      128          *:15672                    *:*                   users:(("beam.smp",pid=3593,fd=93)) LISTEN     0      128         :::5672                    :::*                   users:(("beam.smp",pid=3593,fd=92))

負載均衡

我們這裡用haproxy做負載均衡 ,haproxy 啟動配置省略,這個地方負責內外的負載均衡,如需外網啟動,需要做轉發既可。

增加VIP

ip addr add 192.168.100.242/24 dev eth0:mq

ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 5a:fd:bf:c3:43:ec brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.217/24 brd 192.168.100.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.100.242/24 scope global secondary eth0
       valid_lft forever preferred_lft forever

配置檔案

➜  vim /opt/rabbitmq_server-3.8.5/etc/haproxy.cnf
global
    log     127.0.0.1  local0 info
    log     127.0.0.1  local1 notice
    daemon
    maxconn 4096

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    retries 3
    option  abortonclose
    maxconn 4096
    timeout connect  5000ms
    timeout client  3000ms
    timeout server  3000ms
    balance roundrobin

listen private_monitoring
    bind    192.168.100.242:8100
    mode    http
    option  httplog
    stats   refresh  5s
    stats   uri  /stats
    stats   realm   Haproxy
    stats   auth  admin:admin

listen rabbitmq_cluster
    bind    192.168.100.242:8101
    mode    tcp
    option  tcplog
    balance roundrobin
    server  MQ1  192.168.100.217:5672  check  inter  5000  rise  2  fall  3
    server  MQ2  192.168.100.218:5672  check  inter  5000  rise  2  fall  3
    server  MQ3  192.168.100.219:5672  check  inter  5000  rise  2  fall  3

listen rabbitmq_admin
    bind    192.168.100.242:8102
    server  MQ1  192.168.100.217:15672
    server  MQ2  192.168.100.218:15672
    server  MQ3  192.168.100.219:15672

啟動haproxy

➜  haproxy -f /opt/rabbitmq_server-3.8.5/etc/haproxy.cnf

參考連結:

參考連結:
1、官方二進位制手冊
2、官方叢集手冊
3、https://www.jianshu.com/p/97fbf9c82872
4、https://my.oschina.net/genghz/blog/1840262
5、https://www.jianshu.com/p/d55fcee12918
6、https://www.jianshu.com/p/7cf2ad01c422
7、https://blog.csdn.net/yujin2010good/article/details/73614507
8、http://www.haproxy.org/
9、https://blog.csdn.net/winy_lm/article/details/81128181
10、https://www.cnblogs.com/knowledgesea/p/6535766.html