RabbitMQ(四):使用Docker構建RabbitMQ高可用負載均衡叢集
本文使用Docker搭建RabbitMQ叢集,然後使用HAProxy做負載均衡,最後使用KeepAlived實現叢集高可用,從而搭建起來一個完成了RabbitMQ高可用負載均衡叢集。受限於自身條件,本文使用VMware虛擬機器的克隆功能克隆了兩臺伺服器進行操作,僅作為一個demo,開發中可根據實際情況進行調整。
首先看下RabbitMQ高可用負載均衡叢集長什麼樣子:
使用Docker構建RabbitMQ高可用負載均衡叢集大概分為三個步驟:
- 啟動多個(3個為例)RabbitMQ,構建RabbitMQ叢集,並配置為映象模式。
- 使用HAProxy做負載均衡。
- 使用KeepAlived實現高可用。
一、構建RabbitMQ叢集
1. 啟動多個RabbitMQ節點
使用Docker啟動3個RabbitMQ節點,目標如下表所示:
伺服器ip | 埠 | hostname | 管理介面地址 |
---|---|---|---|
192.168.16.128 | 5672 | my-rabbit1 | 192.168.16.128:15672 |
192.168.16.128 | 5673 | my-rabbit2 | 192.168.16.128:15673 |
192.168.16.128 | 5674 | my-rabbit3 | 192.168.16.128:15674 |
命令:
docker run -d --hostname my-rabbit1 --name rabbit1 -p 5672:5672 -p 15672:15672 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.8.0-beta.4-management docker run -d --hostname my-rabbit2 --name rabbit2 -p 5673:5672 -p 15673:15672 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' --link rabbit1:my-rabbit1 rabbitmq:3.8.0-beta.4-management docker run -d --hostname my-rabbit3 --name rabbit3 -p 5674:5672 -p 15674:15672 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' --link rabbit1:my-rabbit1 --link rabbit2:my-rabbit2 rabbitmq:3.8.0-beta.4-management
注意:由於Erlang節點間通過認證Erlang cookie的方式來允許互相通訊,所以RABBITMQ_ERLANG_COOKIE必須設定為相同的。
啟動完成之後,使用docker ps命令檢視執行情況,確保RabbitMQ都已經啟動。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2d6f612fdc8e rabbitmq:3.8.0-beta.4-management "docker-entrypoint..." 5 seconds ago Up 4 seconds 4369/tcp, 5671/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:5674->5672/tcp, 0.0.0.0:15674->15672/tcp rabbit3 c410aa73ce68 rabbitmq:3.8.0-beta.4-management "docker-entrypoint..." 14 seconds ago Up 14 seconds 4369/tcp, 5671/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:5673->5672/tcp, 0.0.0.0:15673->15672/tcp rabbit2 ceb28620d7b1 rabbitmq:3.8.0-beta.4-management "docker-entrypoint..." 24 seconds ago Up 23 seconds 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp rabbit1
2. 加入叢集
記憶體節點和磁碟節點的選擇:
每個RabbitMQ節點,要麼是記憶體節點,要麼是磁碟節點。記憶體節點將所有的佇列、交換器、繫結、使用者等元資料定義都儲存在記憶體中;而磁碟節點將元資料儲存在磁碟中。單節點系統只允許磁碟型別的節點,否則當節點重啟以後,所有的配置資訊都會丟失。如果採用叢集的方式,可以選擇至少配置一個節點為磁碟節點,其餘部分配置為記憶體節點,,這樣可以獲得更快的響應。所以本叢集中配置節點1位磁碟節點,節點2和節點3位記憶體節點。
叢集中的第一個節點將初始元資料代入叢集中,並且無須被告知加入。而第2個和之後加入的節點將加入它並獲取它的元資料。要加入節點,需要進入Docker容器,重啟RabbitMQ。
設定節點1:
docker exec -it rabbit1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit
設定節點2:
docker exec -it rabbit2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@my-rabbit1
rabbitmqctl start_app
exit
設定節點3:
docker exec -it rabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@my-rabbit1
rabbitmqctl start_app
exit
節點設定完成之後,在瀏覽器訪問192.168.16.128:15672、192.168.16.128:15673和192.168.16.128:15674中任意一個,都會看到RabbitMQ叢集已經建立成功。
3. 配置映象佇列
映象佇列工作原理:在非映象佇列的叢集中,訊息會路由到指定的佇列。當配置為映象佇列之後,訊息除了按照路由規則投遞到相應的佇列外,還會投遞到映象佇列的拷貝。也可以想象在映象佇列中隱藏著一個fanout交換器,將訊息傳送到映象的佇列的拷貝。
進入任意一個RabbitMQ節點,執行如下命令:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
可以設定映象佇列,"^"表示匹配所有佇列,即所有佇列在各個節點上都會有備份。在叢集中,只需要在一個節點上設定映象佇列,設定操作會同步到其他節點。
檢視叢集的狀態:
rabbitmqctl cluster_status
二、HAProxy負載均衡
第一步構建RabbitMQ叢集只是構建高可用負載均衡叢集的基礎,下面將使用HAProxy為RabbitMQ叢集做負載均衡。
Haproxy 是目前比較流行的一種群集排程工具,是使用C語言編寫的自由及開放原始碼軟體,其提供高可用性、負載均衡,以及基於TCP和HTTP的應用程式代理。同類群集排程工具有很多,如LVS 和 Nginx 。相比較而言,LVS 效能最好,但是搭建相對複雜,Nginx的upstream模組支援群集功能,但是對群集節點的健康檢查功能不強,效能沒有HAProxy 好。
對於排程演算法本文采用最簡單最常用的輪詢演算法。
本來想採用Docker的方式拉取並執行HAProxy映象,折騰了好幾天搞不定,HAProxy啟動不了,故採用原始碼安裝的方式安裝HAProxy。
配置兩個HAProxy節點實現負載均衡:
伺服器ip | 埠號 | 管理介面地址 |
---|---|---|
192.168.16.128 | 8888 | http://192.168.16.128:8888/haproxy |
192.168.16.129 | 8888 | http://192.168.16.129:8888/haproxy |
1. 安裝HAProxy
- 下載
由於到官網下載需要kexue上網,這裡提供百度雲連結。
連結: https://pan.baidu.com/s/1uaSJa3NHFiE1E6dk7iHMwQ 提取碼: irz6
- 將haproxy-1.7.8.tar.gz拷貝至/opt目錄下,解壓縮:
tar zxvf haproxy-1.7.8.tar.gz
- 進入目錄,編譯成可執行檔案。
將原始碼解壓之後,需要執行make來將HAProxy編譯成為可執行檔案。如果是在Linux2.6系統上面進行編譯的話,需要設定TARGET=linux26以開啟epoll支援,這也是為什麼網上許多部落格裡面都是這麼寫的。對於其他的UNIX系統來說,直接採用TARGET=generic方式,本文進行安裝的系統為CentOS7 ,核心3.10版本。
cd haproxy-1.7.8
make TARGET=generic
執行完畢之後,目錄下出現haproxy的可執行檔案。
2. 配置HAProxy
HAProxy配置檔案說明
HAProxy配置檔案通常分為三個部分,即global、defaults和listen。global為全域性配置,defaults為預設配置,listen為應用元件配置。
global為全域性配置部分,屬於程序級別的配置,通常和使用的作業系統配置相關。
defaults配置項配置預設引數,會被應用元件繼承,如果在應用元件中沒有特別宣告,將使用預設配置引數。
以配置RabbitMQ叢集的負載均衡為例,在安裝目錄下面新建一個haproxy.cfg,輸入下面配置資訊:
global
#日誌輸出配置,所有日誌都記錄在本機,通過local0輸出
log 127.0.0.1 local0 info
#最大連線數
maxconn 10240
#以守護程序方式執行
daemon
defaults
#應用全域性的日誌配置
log global
mode http
#超時配置
timeout connect 5000
timeout client 5000
timeout server 5000
timeout check 2000
listen http_front #haproxy的客戶頁面
bind 192.168.16.128:8888
mode http
option httplog
stats uri /haproxy
stats auth admin:123456
stats refresh 5s
stats enable
listen haproxy #負載均衡的名字
bind 0.0.0.0:5666 #對外提供的虛擬的埠
option tcplog
mode tcp
#輪詢演算法
balance roundrobin
server rabbit1 192.168.16.128:5672 check inter 5000 rise 2 fall 2
server rabbit2 192.168.16.128:5673 check inter 5000 rise 2 fall 2
server rabbit3 192.168.16.128:5674 check inter 5000 rise 2 fall 2
3. 啟動
啟動命令:
/opt/haproxy-1.7.8/haproxy -f /opt/haproxy-1.7.8/haproxy.cfg
驗證一下是否啟動成功:
[root@localhost haproxy-1.7.8]# lsof -i:8888
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
haproxy 45031 root 3u IPv4 228341 0t0 TCP localhost.localdomain:ddi-tcp-1 (LISTEN)
在瀏覽器上訪問http://192.168.16.128:8888/haproxy,輸入配置的使用者名稱和密碼登入以後,可以看到如下畫面:
再以相同的方式在192.168.16.129伺服器上面啟動一個HAProxy。
到此,負載均衡配置完成。
三、KeepAlived配置高可用
Keepalived,它是一個高效能的伺服器高可用或熱備解決方案,Keepalived主要來防止伺服器單點故障的發生問題,可以通過其與Nginx、Haproxy等反向代理的負載均衡伺服器配合實現web服務端的高可用。Keepalived以VRRP協議為實現基礎,用VRRP協議來實現高可用性(HA)。
1. KeepAlived安裝
Keepalived的官網下載Keepalived的安裝檔案,目前最新的版本為:keepalived-2.0.17.tar.gz,下載地址為http://www.keepalived.org/download.html。
下載之後進行解壓和編譯安裝。
tar zxvf keepalived-2.0.17.tar.gz
cd keepalived-2.0.17
./configure --prefix=/opt/keepalived --with-init=SYSV
#注:(upstart|systemd|SYSV|SUSE|openrc) #根據你的系統選擇對應的啟動方式
make
make install
2. KeepAlived配置
之後將安裝過後的Keepalived加入系統服務中,詳細步驟如下:
cp /opt/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp /opt/keepalived/etc/sysconfig/keepalived /etc/sysconfig
cp /opt/keepalived/sbin/keepalived /usr/sbin/
chmod +x /etc/init.d/keepalived
chkconfig --add keepalived
chkconfig keepalived on
#Keepalived預設會讀取/etc/keepalived/keepalived.conf配置檔案
mkdir /etc/keepalived
cp /opt/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
接下來修改/etc/keepalived/keepalived.conf檔案,在Keepalived的Master上配置詳情如下:
#Keepalived配置檔案
global_defs {
router_id NodeA #路由ID, 主備的ID不能相同
}
#自定義監控指令碼
vrrp_script chk_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 5
weight 2
}
vrrp_instance VI_1 {
state MASTER #Keepalived的角色。Master表示主伺服器,從伺服器設定為BACKUP
interface eth0 #指定監測網絡卡
virtual_router_id 1
priority 100 #優先順序,BACKUP機器上的優先順序要小於這個值
advert_int 1 #設定主備之間的檢查時間,單位為s
authentication { #定義驗證型別和密碼
auth_type PASS
auth_pass root123
}
track_script {
chk_haproxy
}
virtual_ipaddress { #VIP地址,可以設定多個:
192.168.16.130
}
}
Backup中的配置大致和Master中的相同,不過需要修改global_defs{}的router_id,比如置為NodeB;其次要修改vrrp_instance VI_1{}中的state為BACKUP;最後要將priority設定為小於100的值。注意Master和Backup中的virtual_router_id要保持一致。下面簡要的展示下Backup的配置:
#Keepalived配置檔案
global_defs {
router_id NodeB #路由ID, 主備的ID不能相同
}
#自定義監控指令碼
vrrp_script chk_haproxy {
script "/etc/keepalived/check_haproxy.sh"
interval 5
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0 #指定監測網絡卡
virtual_router_id 1
priority 80 #優先順序,BACKUP機器上的優先順序要小於這個值
advert_int 1 #設定主備之間的檢查時間,單位為s
authentication { #定義驗證型別和密碼
auth_type PASS
auth_pass root123
}
track_script {
chk_haproxy
}
virtual_ipaddress { #VIP地址,可以設定多個:
192.168.16.130
}
}
為了防止HAProxy服務掛了,但是Keepalived卻還在正常工作而沒有切換到Backup上,所以這裡需要編寫一個指令碼來檢測HAProxy服務的狀態。當HAProxy服務掛掉之後該指令碼會自動重啟HAProxy的服務,如果不成功則關閉Keepalived服務,如此便可以切換到Backup繼續工作。這個指令碼就對應了上面配置中vrrp_script chk_haproxy{}的script對應的值,/etc/keepalived/check_haproxy.sh的內容如程式碼清單所示。
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
haproxy -f /opt/haproxy-1.7.8/haproxy.cfg
fi
sleep 2
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
service keepalived stop
fi
如此配置好之後,使用service keepalived start命令啟動192.168.16.128和192.168.16.129中的Keepalived服務即可。之後客戶端的應用可以通過192.168.16.130這個IP地址來接通RabbitMQ服務