RabbitMQ(四):使用Docker構(gòu)建RabbitMQ高可用負(fù)載均衡集群

本文使用Docker搭建RabbitMQ集群,然后使用HAProxy做負(fù)載均衡,最后使用KeepAlived實(shí)現(xiàn)集群高可用,從而搭建起來一個(gè)完成了RabbitMQ高可用負(fù)載均衡集群。受限于自身?xiàng)l件,本文使用VMware虛擬機(jī)的克隆功能克隆了兩臺(tái)服務(wù)器進(jìn)行操作,僅作為一個(gè)demo,開發(fā)中可根據(jù)實(shí)際情況進(jìn)行調(diào)整。

首先看下RabbitMQ高可用負(fù)載均衡集群長(zhǎng)什么樣子:

image

使用Docker構(gòu)建RabbitMQ高可用負(fù)載均衡集群大概分為三個(gè)步驟:

  1. 啟動(dòng)多個(gè)(3個(gè)為例)RabbitMQ,構(gòu)建RabbitMQ集群,并配置為鏡像模式。
  2. 使用HAProxy做負(fù)載均衡。
  3. 使用KeepAlived實(shí)現(xiàn)高可用。

一、構(gòu)建RabbitMQ集群

1. 啟動(dòng)多個(gè)RabbitMQ節(jié)點(diǎn)

使用Docker啟動(dòng)3個(gè)RabbitMQ節(jié)點(diǎn),目標(biāo)如下表所示:

服務(wù)器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節(jié)點(diǎn)間通過認(rèn)證Erlang cookie的方式來允許互相通信,所以RABBITMQ_ERLANG_COOKIE必須設(shè)置為相同的。

啟動(dòng)完成之后,使用docker ps命令查看運(yùn)行情況,確保RabbitMQ都已經(jīng)啟動(dòng)。

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. 加入集群

內(nèi)存節(jié)點(diǎn)和磁盤節(jié)點(diǎn)的選擇:

每個(gè)RabbitMQ節(jié)點(diǎn),要么是內(nèi)存節(jié)點(diǎn),要么是磁盤節(jié)點(diǎn)。內(nèi)存節(jié)點(diǎn)將所有的隊(duì)列、交換器、綁定、用戶等元數(shù)據(jù)定義都存儲(chǔ)在內(nèi)存中;而磁盤節(jié)點(diǎn)將元數(shù)據(jù)存儲(chǔ)在磁盤中。單節(jié)點(diǎn)系統(tǒng)只允許磁盤類型的節(jié)點(diǎn),否則當(dāng)節(jié)點(diǎn)重啟以后,所有的配置信息都會(huì)丟失。如果采用集群的方式,可以選擇至少配置一個(gè)節(jié)點(diǎn)為磁盤節(jié)點(diǎn),其余部分配置為內(nèi)存節(jié)點(diǎn),,這樣可以獲得更快的響應(yīng)。所以本集群中配置節(jié)點(diǎn)1位磁盤節(jié)點(diǎn),節(jié)點(diǎn)2和節(jié)點(diǎn)3位內(nèi)存節(jié)點(diǎn)。

集群中的第一個(gè)節(jié)點(diǎn)將初始元數(shù)據(jù)代入集群中,并且無須被告知加入。而第2個(gè)和之后加入的節(jié)點(diǎn)將加入它并獲取它的元數(shù)據(jù)。要加入節(jié)點(diǎn),需要進(jìn)入Docker容器,重啟RabbitMQ。

設(shè)置節(jié)點(diǎn)1:

docker exec -it rabbit1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

設(shè)置節(jié)點(diǎn)2:

docker exec -it rabbit2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@my-rabbit1
rabbitmqctl start_app
exit

設(shè)置節(jié)點(diǎn)3:

docker exec -it rabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@my-rabbit1
rabbitmqctl start_app
exit

節(jié)點(diǎn)設(shè)置完成之后,在瀏覽器訪問192.168.16.128:15672、192.168.16.128:15673和192.168.16.128:15674中任意一個(gè),都會(huì)看到RabbitMQ集群已經(jīng)創(chuàng)建成功。

image

3. 配置鏡像隊(duì)列

鏡像隊(duì)列工作原理:在非鏡像隊(duì)列的集群中,消息會(huì)路由到指定的隊(duì)列。當(dāng)配置為鏡像隊(duì)列之后,消息除了按照路由規(guī)則投遞到相應(yīng)的隊(duì)列外,還會(huì)投遞到鏡像隊(duì)列的拷貝。也可以想象在鏡像隊(duì)列中隱藏著一個(gè)fanout交換器,將消息發(fā)送到鏡像的隊(duì)列的拷貝。

進(jìn)入任意一個(gè)RabbitMQ節(jié)點(diǎn),執(zhí)行如下命令:

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

可以設(shè)置鏡像隊(duì)列,"^"表示匹配所有隊(duì)列,即所有隊(duì)列在各個(gè)節(jié)點(diǎn)上都會(huì)有備份。在集群中,只需要在一個(gè)節(jié)點(diǎn)上設(shè)置鏡像隊(duì)列,設(shè)置操作會(huì)同步到其他節(jié)點(diǎn)。

查看集群的狀態(tài):

rabbitmqctl cluster_status

二、HAProxy負(fù)載均衡

第一步構(gòu)建RabbitMQ集群只是構(gòu)建高可用負(fù)載均衡集群的基礎(chǔ),下面將使用HAProxy為RabbitMQ集群做負(fù)載均衡。

Haproxy 是目前比較流行的一種群集調(diào)度工具,是使用C語言編寫的自由及開放源代碼軟件,其提供高可用性、負(fù)載均衡,以及基于TCP和HTTP的應(yīng)用程序代理。同類群集調(diào)度工具有很多,如LVS 和 Nginx 。相比較而言,LVS 性能最好,但是搭建相對(duì)復(fù)雜,Nginx的upstream模塊支持群集功能,但是對(duì)群集節(jié)點(diǎn)的健康檢查功能不強(qiáng),性能沒有HAProxy 好。

對(duì)于調(diào)度算法本文采用最簡(jiǎn)單最常用的輪詢算法。

本來想采用Docker的方式拉取并運(yùn)行HAProxy鏡像,折騰了好幾天搞不定,HAProxy啟動(dòng)不了,故采用源碼安裝的方式安裝HAProxy。

配置兩個(gè)HAProxy節(jié)點(diǎn)實(shí)現(xiàn)負(fù)載均衡:

服務(wù)器ip 端口號(hào) 管理界面地址
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

  1. 下載

由于到官網(wǎng)下載需要kexue上網(wǎng),這里提供百度云鏈接。

鏈接: https://pan.baidu.com/s/1uaSJa3NHFiE1E6dk7iHMwQ 提取碼: irz6

  1. 將haproxy-1.7.8.tar.gz拷貝至/opt目錄下,解壓縮:
tar zxvf haproxy-1.7.8.tar.gz
  1. 進(jìn)入目錄,編譯成可執(zhí)行文件。

將源代碼解壓之后,需要運(yùn)行make來將HAProxy編譯成為可執(zhí)行文件。如果是在Linux2.6系統(tǒng)上面進(jìn)行編譯的話,需要設(shè)置TARGET=linux26以開啟epoll支持,這也是為什么網(wǎng)上許多博客里面都是這么寫的。對(duì)于其他的UNIX系統(tǒng)來說,直接采用TARGET=generic方式,本文進(jìn)行安裝的系統(tǒng)為CentOS7 ,內(nèi)核3.10版本。

cd haproxy-1.7.8
make TARGET=generic

執(zhí)行完畢之后,目錄下出現(xiàn)haproxy的可執(zhí)行文件。

2. 配置HAProxy

HAProxy配置文件說明

HAProxy配置文件通常分為三個(gè)部分,即global、defaults和listen。global為全局配置,defaults為默認(rèn)配置,listen為應(yīng)用組件配置。

global為全局配置部分,屬于進(jìn)程級(jí)別的配置,通常和使用的操作系統(tǒng)配置相關(guān)。

defaults配置項(xiàng)配置默認(rèn)參數(shù),會(huì)被應(yīng)用組件繼承,如果在應(yīng)用組件中沒有特別聲明,將使用默認(rèn)配置參數(shù)。

以配置RabbitMQ集群的負(fù)載均衡為例,在安裝目錄下面新建一個(gè)haproxy.cfg,輸入下面配置信息:

global
  #日志輸出配置,所有日志都記錄在本機(jī),通過local0輸出
  log 127.0.0.1 local0 info
  #最大連接數(shù)
  maxconn 10240
  #以守護(hù)進(jìn)程方式運(yùn)行
  daemon

defaults
  #應(yīng)用全局的日志配置
  log global
  mode http
  #超時(shí)配置
  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 #負(fù)載均衡的名字
  bind 0.0.0.0:5666 #對(duì)外提供的虛擬的端口
  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. 啟動(dòng)

啟動(dòng)命令:

/opt/haproxy-1.7.8/haproxy -f /opt/haproxy-1.7.8/haproxy.cfg

驗(yàn)證一下是否啟動(dòng)成功:

[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,輸入配置的用戶名和密碼登錄以后,可以看到如下畫面:

image

再以相同的方式在192.168.16.129服務(wù)器上面啟動(dòng)一個(gè)HAProxy。

到此,負(fù)載均衡配置完成。

三、KeepAlived配置高可用

Keepalived,它是一個(gè)高性能的服務(wù)器高可用或熱備解決方案,Keepalived主要來防止服務(wù)器單點(diǎn)故障的發(fā)生問題,可以通過其與Nginx、Haproxy等反向代理的負(fù)載均衡服務(wù)器配合實(shí)現(xiàn)web服務(wù)端的高可用。Keepalived以VRRP協(xié)議為實(shí)現(xiàn)基礎(chǔ),用VRRP協(xié)議來實(shí)現(xiàn)高可用性(HA)。

1. KeepAlived安裝

Keepalived的官網(wǎng)下載Keepalived的安裝文件,目前最新的版本為:keepalived-2.0.17.tar.gz,下載地址為http://www.keepalived.org/download.html。

下載之后進(jìn)行解壓和編譯安裝。

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) #根據(jù)你的系統(tǒng)選擇對(duì)應(yīng)的啟動(dòng)方式
make
make install

2. KeepAlived配置

之后將安裝過后的Keepalived加入系統(tǒng)服務(wù)中,詳細(xì)步驟如下:

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默認(rèn)會(huì)讀取/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不能相同
}

#自定義監(jiān)控腳本
vrrp_script chk_haproxy {
        script "/etc/keepalived/check_haproxy.sh"
        interval 5
        weight 2
}

vrrp_instance VI_1 {
        state MASTER #Keepalived的角色。Master表示主服務(wù)器,從服務(wù)器設(shè)置為BACKUP
        interface eth0          #指定監(jiān)測(cè)網(wǎng)卡
        virtual_router_id 1
        priority 100            #優(yōu)先級(jí),BACKUP機(jī)器上的優(yōu)先級(jí)要小于這個(gè)值
        advert_int 1            #設(shè)置主備之間的檢查時(shí)間,單位為s
        authentication {        #定義驗(yàn)證類型和密碼
                auth_type PASS
                auth_pass root123
        }
        track_script {
                chk_haproxy
        }
        virtual_ipaddress {     #VIP地址,可以設(shè)置多個(gè):
                192.168.16.130
        }
}

Backup中的配置大致和Master中的相同,不過需要修改global_defs{}的router_id,比如置為NodeB;其次要修改vrrp_instance VI_1{}中的state為BACKUP;最后要將priority設(shè)置為小于100的值。注意Master和Backup中的virtual_router_id要保持一致。下面簡(jiǎn)要的展示下Backup的配置:

#Keepalived配置文件
global_defs {
        router_id NodeB                 #路由ID, 主備的ID不能相同
}

#自定義監(jiān)控腳本
vrrp_script chk_haproxy {
        script "/etc/keepalived/check_haproxy.sh"
        interval 5
        weight 2
}

vrrp_instance VI_1 {
        state BACKUP
        interface eth0          #指定監(jiān)測(cè)網(wǎng)卡
        virtual_router_id 1
        priority 80            #優(yōu)先級(jí),BACKUP機(jī)器上的優(yōu)先級(jí)要小于這個(gè)值
        advert_int 1            #設(shè)置主備之間的檢查時(shí)間,單位為s
        authentication {        #定義驗(yàn)證類型和密碼
                auth_type PASS
                auth_pass root123
        }
        track_script {
                chk_haproxy
        }
        virtual_ipaddress {     #VIP地址,可以設(shè)置多個(gè):
                192.168.16.130
        }
}

為了防止HAProxy服務(wù)掛了,但是Keepalived卻還在正常工作而沒有切換到Backup上,所以這里需要編寫一個(gè)腳本來檢測(cè)HAProxy服務(wù)的狀態(tài)。當(dāng)HAProxy服務(wù)掛掉之后該腳本會(huì)自動(dòng)重啟HAProxy的服務(wù),如果不成功則關(guān)閉Keepalived服務(wù),如此便可以切換到Backup繼續(xù)工作。這個(gè)腳本就對(duì)應(yīng)了上面配置中vrrp_script chk_haproxy{}的script對(duì)應(yīng)的值,/etc/keepalived/check_haproxy.sh的內(nèi)容如代碼清單所示。

#!/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命令啟動(dòng)192.168.16.128和192.168.16.129中的Keepalived服務(wù)即可。之后客戶端的應(yīng)用可以通過192.168.16.130這個(gè)IP地址來接通RabbitMQ服務(wù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容