可以參考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)實現高可用功能(主備切換)。

注意: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集群配置
我們這里以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會有三個節點:

安裝 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,可以看到:

安裝 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:

node5:

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

node5:

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

當node4恢復服務時,它就會從node5中奪回VIP,重新作為MASTER節點。
集群恢復與故障轉移
場景1:

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

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

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

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

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

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