RabbitMQ集群搭建-鏡像模式


可以參考https://blog.csdn.net/wexiaoword/article/details/81352045

 

服務器介紹

node1:192.168.174.10
node2:192.168.174.11
node3:192.168.174.12
node4:192.168.174.13
node5:192.168.174.14
其中,node1、node2、node3三台服務器安裝RabbitMQ服務,node4和node5安裝HA-proxy和Keepalived。

服務集群架構

  • HA-proxy


     
    Haproxy 介紹

以常見的TCP應用為例,負載均衡器在接收到第一個來自客戶端的SYN請求時,會通過設定的負載均衡算法選擇一個最佳的后端服務器,同時將報文中目標IP地址修改為后端服務器IP,然后直接轉發給該后端服務器,這樣一個負載均衡請求就完成了。從這個過程來看,一個TCP連接是客戶端和服務器直接建立的,而負載均衡器只不過完成了一個類似路由器的轉發動作。在某些負載均衡策略中,為保證后端服務器返回的報文可以正確傳遞給負載均衡器,在轉發報文的同時可能還會對報文原來的源地址進行修改。整個過程下圖所示

 
 

Haproxy 的特點是:高可用,負載均衡。

  • KeepAlived


     
    KeepAlived 介紹

KeepAlived 的特點:通過VRRP協議(虛擬ip)實現高可用功能(主備切換)。

 
KeepAlived 高可用原理

注意:master節點恢復時,是否重新接管master角色,看我們自己的配置,后面配置KeepAlived會講。

  • 鏡像模式
    鏡像模式,是中小型企業常用的rabbitmq集群架構:
     
    鏡像模式架構圖

    消息的發布(除了Basic.Publish之外)與消費都是通過master節點完成。master節點對消息進行處理的同時將消息的處理動作通過GM(Guarenteed Multicast)廣播給所有的slave節點,slave節點的GM收到消息后,通過回調交由mirror_queue_slave進行實際的處理。
    鏡像模式流程:程序(Springboot Application)通過訪問 KeepAlived 提供的VIP(虛擬ip)指定到其中一個HA-proxy,然后 HA-proxy將訪問請求代理到其管理的三個(或多個)rabbitmq server 中的一個,從而實現了高可用、負載均衡的功能。

RabbitMQ主從配置

  • RabbitMQ安裝(node1,node2,node3)
    首先配置5個服務器hosts文件:
192.168.174.10  node1
192.168.174.11  node2
192.168.174.12  node3
192.168.174.13  node4
192.168.174.14  node5

1、安裝gcc環境

yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel libxml2-utils libxml2 libxslt openssl-devel unixODBC unixODBC-devel unixODBC-bin gtk2 fop gtk2-devel binutils-devel mesa-libGLU-devel yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel libxml2-utils libxml2 libxslt openssl-devel unixODBC unixODBC-devel unixODBC-bin gtk2 fop gtk2-devel binutils-devel mesa-libGLU-devel

2、安裝erlang
下載地址為:http://www.erlang.org/downloads,我這里下載的是otp_src_20.1.tar.gz
解壓、配置、編譯:

tar -xvf otp_src_20.1.tar.gz
cd otp_src_20.1
./configure --prefix=/usr/local/erlang20 --without-javac
make && make install

如果報 Java compiler disabled by user 錯誤,則去掉--without-javac
3、安裝 RabbitMQ
安裝 python

yum install python -y

安裝 simplejson

yum install xmlto -y
yum install python-simplejson -y

rabbitmq下載地址:http://www.rabbitmq.com/download.html,我這里下載的是rabbitmq-server-generic-unix-3.6.14.tar
解壓,並移至/usr/local/rabbitmq

tar -xvf rabbitmq-server-generic-unix-3.6.14.tar
mv rabbitmq_server-3.6.14 /usr/local/rabbitmq

設置環境變量

export PATH=$PATH:/usr/local/erlang20/bin:/usr/local/rabbitmq/sbin
source /etc/profile

啟動rabbitmq

./rabbitmq-server &
加上& 就是后台啟動,./rabbitmqctl stop 為停止服務

設置guest可以遠程連接
修改rabbitmq的配置/usr/local/rabbitmq/etc/rabbitmq/rabbitmq.config(沒有就新建)
添加:

[{rabbit, [{loopback_users, []}]}].

啟用管理控制台

./rabbitmq-plugins enable rabbitmq_management

重啟 rabbitmq,打開瀏覽器訪問:http://node1:15672,用戶名guest,密碼guest。node2和node3安裝略。

 
rabbitmq 管理台

 

  • RabbitMQ集群配置
    我們這里以node1為master節點,node2和node3為slave節點。
    1、停止MQ服務

rabbimqctl stop

2、復制node1節點的/root/.erlang.cookie文件到其他節點,並覆蓋

scp /root/.erlang.cookie root@node2:~
scp /root/.erlang.cookie root@node3:~

3、啟動集群

rabbitmq-server -datached

4、slave 加入集群,對node2和node3分別執行下面操作

rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@node1
rabbitmqctl start_app

如果需要移除集群節點,執行下面命令:

rabbitmqctl forget_cluster_node rabbit@node2(具體節點)

5、修改集群名稱(任意一個節點操作,默認為master node名稱)

rabbitmqctl set_cluster_name rabbitmq_cluster1

6、查看集群狀態(任意一個節點操作)

rabbitmqctl cluster_status

7、設置鏡像隊列策略(任意一個節點操作)

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

將所有隊列設置為鏡像隊列,即隊列會被復制到各個節點,各個節點狀態一致。
此時看rabbitmq管控台,Nodes會有三個節點:


 
rabbitmq 集群

安裝 Haproxy(node4和node5)

1、下載依賴包

yum install gcc

2、下載haproxy

yum install haproxy -y

3、編輯 haproxy 配置文件

vi /etc/haproxy/haproxy.cfg

新增listen內容,根據實際情況,修改default內容:

#logging options
global
    log 127.0.0.1 local0 info
    maxconn 5120
    chroot /usr/local/haproxy
    uid 99
    gid 99
    daemon
    quiet
    nbproc 20
    pidfile /var/run/haproxy.pid
    
defaults
    log global
    # 使用四層代理模式,"mode http" 為7層代理模式
    mode tcp
    # if you set mode to tcp,then you must change tcplog into httplog
    option tcplog
    option dontlognull
    retries 3
    option redispatch
    maxconn 2000
    contimeout 5s
    # 客戶端空閑超時時間為60秒,過了該時間,HA發起重連機制
    clitimeout 60s
    # 服務端連接超時時間為15秒,過了該時間,HA發起重連機制
    srvtimeout 15s

listen rabbitmq_cluster
    # 定義監聽地址和端口,本機的5672端口
    bind 0.0.0.0:5672
    # 配置 tcp 模式
    mode tcp
    # balance url_param userid
    # balance url_param session_id check_post 64
    # 簡單的輪詢
    balance roundrobin
    #rabbitmq集群節點配置 #inter 每隔五秒對mq集群做健康檢查,2次正確證明服務器可用,
    #2次失敗證明服務器不可用,並且配置主備機制
    server node1 192.168.174.10:5672 check inter 5000 rise 2 fall 2
    server node2 192.168.174.11:5672 check inter 5000 rise 2 fall 2
    server node3 192.168.174.12:5672 check inter 5000 rise 2 fall 2
        
# 配置 haproxy web 監控,查看統計信息
listen stats
    bind *:8100
    mode http
    option httplog
    stats enable
    # 設置 haproxy 監控地址為:http://localhost:8100/rabbitmq-stats
    stats uri /rabbitmq-stats
    stats refresh 5s

4、啟動haproxy

haproxy -f /etc/haproxy/haproxy.cfg

重啟haproxy:service haproxy restart
至此,haproxy配置成功,可以訪問:http://192.168.174.13:8100/rabbitmq-stats,可以看到:

 
haproxy 監控台

 

安裝 Keepalived(node4和node5)

我這里將node4作為keepalived的主節點,node5為備用節點。並且node4宕機恢復服務后,需要搶回VIP。
1、安裝所需軟件包

yum install -y openssl openssl-devel

2、下載 keepalived

wget http://www.keepalived.org/software/keepalived-1.2.18.tar.gz

3、解壓、編譯、安裝

tar -xvf keepalived-1.2.18.tar.gz
cd keepalived-1.2.18
./configure --prefix=/usr/local/keepalived
make && make install

4、創建文件夾,將keepalived配置文件進行復制

mkdir /etc/keepalived
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig

5、創建軟連接,如果存在則進行刪除

ln -s /usr/local/sbin/keepalived /usr/sbin
ln -s /usr/local/keepalived/sbin/keepalived /sbin

6、設置開機啟動

chkconfig keepalived on

7、編輯 keepalived 配置文件

vi /etc/keepalived/keepalived.conf

node4的內容如下:

! Configuration File for keepalived global defs { router_id node4 ##標識節點的字符串,通常為hostname } vrrp_script chk_haproxy{ script "/etc/keepalived/haproxy_check.sh" ## 執行腳本位置 interval 2 ##檢查時間間隔 weight -20 ##如果條件成立則權重減20 } vrrp_instance VI_1 { state MASTER##主節點為MASTER,備份節點為BACKUP interface ens33 ##綁定虛擬ip的網絡接口(網卡) virtual_router_id 13 ##虛擬路由id號,主備節點相同 mcast_src_ip 192.168.174.13 ##本機ip地址 priority 100 ##優先級(0-254) nopreempt advert_int 1 ##組播信息發送間隔,兩個節點必須一致,默認1s authentication { ##認證匹配 auth_type PASS auth_pass bhz } track_script { chk_haproxy } virtual_ipaddress { 192.168.174.70 ##虛擬ip,可以指定多個 } } 

node5的內容如下:

! Configuration File for keepalived global defs { router_id node5 ##標識節點的字符串,通常為hostname } vrrp_script chk_haproxy{ script "/etc/keepalived/haproxy_check.sh" ## 執行腳本位置 interval 2 ##檢查時間間隔 weight -20 ##如果條件成立則權重減20 } vrrp_instance VI_1 { state BACKUP ##主節點為MASTER,備份節點為BACKUP interface ens33 ##綁定虛擬ip的網絡接口(網卡) virtual_router_id 13 ##虛擬路由id號,主備節點相同 mcast_src_ip 192.168.174.14 ##本機ip地址 priority 90 ##優先級(0-254) nopreempt advert_int 1 ##組播信息發送間隔,兩個節點必須一致,默認1s authentication { ##認證匹配 auth_type PASS auth_pass bhz } track_script { chk_haproxy } virtual_ipaddress { 192.168.174.70 ##虛擬ip,可以指定多個 } } 

vrrp_instance 的 interface 為VIP需要掛載的網卡上,我這里都放在虛擬機的ens33上。 node4 的 state 為 MASTER,node5 為 BACKUP ,priority 要保證node4大於node5,這樣就能實現node4宕機之后恢復服務,能夠從node5搶回VIP;如果需要實現不搶回VIP,則node4和node5的state都設置為BACKUP,並且vrrp_instance 都添加nopreempt,表示不搶奪VIP(實際上已經加了)。
8、添加執行腳本 haproxy_check.sh

vi /etc/keepalived/haproxy_check.sh

內容如下(node4和node5一樣):

#!/bin/bash
COUNT = `ps -C haproxy --no-header | wc -l`
if [$COUNT -eq 0];then
    /usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
    sleep 2
    if[`ps -C haproxy --no-header | wc -l` -eq 0];then
        killall keepalived
    fi
fi

9、賦予腳本執行權限

chmod +x haproxy_check.sh

10、啟動keepalived

service keepalived start

至此,基於Keepalived和Haproxy的rabbitmq集群,已經搭接完成。
下面我們來測試下keepalived的VIP切換:
當node4和node5都成功啟動keepalived時,我們使用命令ip a查看當前服務器的ip:
node4:


 
node4 master

node5:


 
node5 backup

此時,VIP落在了node4上,所以node4為master節點,node5為備用節點。
現在,我們讓node4的keepalived宕機:
 
node4 宕機

node5:
 
node5 奪取vip

當node4的keepalived宕機之后,VIP就被node5拿去了,這樣就實現了主備切換的功能。
現在我們讓node4的keepalived服務恢復:


 
node4 恢復服務

當node4恢復服務時,它就會從node5中奪回VIP,重新作為MASTER節點。

集群恢復與故障轉移

場景1:


 
場景1

由於節點B是后停的,所以數據是最新的,並且B是Mater節點。所以先啟動B,再啟動A即可;如果A(slave)先啟動,它會有30s的等待時間,等待master的啟動,然后加入cluster中(如果30s內master沒有啟動,slave會自動停止)。
場景2:


 
場景2

當所有節點因故障(斷電等)同時離線時,每個節點都認為自己不是最后一個停止的節點。要恢復鏡像隊列,可以嘗試在30s之內啟動所有節點。
場景3:
 
場景3

由於A無法恢復,於是需要棄用A,因為B是Master並且是可以恢復的,於是我們可以啟動B,然后執行:rabbitmqctl forget_cluster_node A,解除與A的cluster關系。再將新的slave節點加入B即可重新恢復鏡像隊列。
場景4:


 
場景4

由於B是Master,但是無法啟動,於是作為Slave的A,也是無法啟動的。因為如果slave在30s內沒有監聽到master的信息,則會自行斷開。所以,我們需要線下去掉B,執行:rabbitmqctl forget_cluster_node B --offline。
場景5:
 
場景5

由於A、B都無法恢復,於是我們都得棄用。我們拿到A或者B的磁盤文件,copy到新的服務器對應的目錄下。
場景6:
 
場景6



作者:habit_learning
鏈接:https://www.jianshu.com/p/5b2879fba25b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM