Docker搭建多機多節(jié)點haproxy+keepalived負載均衡的高可用RabbitMQ集群

本文為多宿主搭建徒溪,單機搭建可參考下方文章
https://www.cnblogs.com/CaesarLinsa/p/11037613.html

??坑很多,配置要求比較嚴苛金顿,請注意

??多物理機搭建最大的問題是臊泌,默認bridge網(wǎng)絡模式下docker容器使用的是bridge按照DHCP協(xié)議動態(tài)分配的子網(wǎng)IP,容器是虛擬網(wǎng)絡容器揍拆,相對于外部網(wǎng)絡是隔離的渠概,所以無法通過hosts解析到外部IP,也無從連接其他mq節(jié)點

多宿主集群當前已知的搭建模式有:
① host的網(wǎng)絡模式(- -net host)
② 插件(Calico flannel weave Docker Overlay)
③ overlay的網(wǎng)絡模式
④ 內(nèi)網(wǎng)DNS服務器提供域名解析

??這里提供host網(wǎng)絡模式的集群搭建,以兩臺物理機為例播揪,網(wǎng)絡環(huán)境為內(nèi)網(wǎng)

172.16.22.72 (主機)
172.16.22.59 (備機)
172.16.22.240(VIP)

(零)贮喧、架構圖

image

(一)、創(chuàng)建MQ容器

??兩種方法均可猪狈,均為增加hosts映射關系進行節(jié)點尋址箱沦,最終產(chǎn)出相同。建議采用方法一 雇庙,后續(xù)節(jié)點擴增更靈活

  • 方法一

1.創(chuàng)建hosts
兩臺機器都創(chuàng)建/opt/rabbitmq目錄谓形,然后在rabbitmq目錄下創(chuàng)建hosts文件

mkdir /opt/rabbitmq
cd /opt/rabbitmq
vi hosts
#ip            真實主機hostname(如果主機名為localhost會有一點問題,建議更改)
172.16.22.72   support
172.16.22.59   hr02

2.運行容器
當docker發(fā)現(xiàn)本地沒有 rabbitmq:management 的鏡像時會主動從倉庫拉取疆前,management 為帶有管理頁面的版本

#172.16.22.72
docker run -d --net host --name rabbit1  -v /opt/rabbitmq:/var/lib/rabbitmq:z  -v /opt/rabbitmq/hosts:/etc/hosts -e RABBITMQ_ERLANG_COOKIE='RABBITMQ'  rabbitmq:management
#172.16.22.59
docker run -d --net host --name rabbit2  -v /opt/rabbitmq:/var/lib/rabbitmq:z  -v /opt/rabbitmq/hosts:/etc/hosts -e RABBITMQ_ERLANG_COOKIE='RABBITMQ'  rabbitmq:management
  • 方法二
#172.16.22.72
docker run -d --net host --name rabbit1 --add-host=support:172.16.22.72 --add-host=hr02:172.16.22.59 -e RABBITMQ_ERLANG_COOKIE='RABBITMQ'  rabbitmq:management
#172.16.22.59
docker run -d --net host --name rabbit2 --add-host=support:172.16.22.72 --add-host=hr02:172.16.22.59 -e RABBITMQ_ERLANG_COOKIE='RABBITMQ'  rabbitmq:management

??【可選】

??如果要將文件映射到宿主機方便以后遷移備份寒跳,可以添加文件映射命令如下。要注意竹椒,添加映射后不會開啟管理頁面的插件童太,需要進入容器手動啟用插件,原因尚未探尋

#etc存放配置胸完,lib存放數(shù)據(jù)庫书释,log存放日志
-v /home/rabbitmq/etc/rabbitmq:/etc/rabbitmq -v /home/rabbitmq/lib/rabbitmq:/var/lib/rabbitmq ->v /home/rabbitmq/log/rabbitmq:/var/log/rabbitmq

??開啟插件

docker exec -it rabbit1 /bin/bash
rabbitmq-plugins enable rabbitmq_management

??【解釋】

#采用host的網(wǎng)絡模式
--net host
#容器命名為rabbit1
--name rabbit1  
#將宿主機的/opt/rabbitmq目錄映射到容器中的/var/lib/rabbitmq目錄,
#z是一個標記赊窥,在selinux環(huán)境下使用
-v /opt/rabbitmq:/var/lib/rabbitmq:z  
#設置env 環(huán)境變量爆惧。這里的cookie可以為任意值,所有節(jié)點保持一致即可
-e RABBITMQ_ERLANG_COOKIE='RABBITMQ'
#增加host
--add-host=support:172.16.22.72

(二)誓琼、搭建集群

??將除了第一個節(jié)點外的其他節(jié)點加入第一個節(jié)點检激,每個節(jié)點都執(zhí)行如下命令。加入節(jié)點時腹侣,
加上--ram 命令則為創(chuàng)建內(nèi)存節(jié)點叔收,不加為硬盤節(jié)點

#進入容器
docker exec -it rabbit2 /bin/bash
#關閉應用
rabbitmqctl stop_app
#清除所有隊列
rabbitmqctl reset
#加入節(jié)點
rabbitmqctl join_cluster --ram rabbit@support
#啟動應用
rabbitmqctl start_app
#查看集群狀態(tài)
rabbitmqctl cluster_status
#【備用】從rabbit@support主節(jié)點上移除rabbit@hr02節(jié)點
rabbitmqctl -n rabbit@support forget_cluster_node rabbit@hr02

image

??【補充】:

tcp4369端口用于集群鄰居發(fā)現(xiàn);
tcp5671傲隶,5672端口用于AMQP 0.9.1 and 1.0 clients使用饺律;
tcp15672端口用于http api與rabbitadmin訪問,后者僅限在management plugin開啟時跺株;
tcp25672端口用于erlang分布式節(jié)點/工具通信

??【個人理解】:
??① 節(jié)點的全稱默認為 【節(jié)點名字@主機名稱】
??② 假定節(jié)點2(hr02)要加入的節(jié)點1的全稱是【rabbit@support】复濒,rabbitmq首先會在同一網(wǎng)段/橋下尋找是否存在該節(jié)點,如果不存在乒省,會在節(jié)點2配置的hosts中尋找support對應的ip巧颈,通過4369端口進行連接。如果連接成功袖扛,節(jié)點2會告知對方砸泛,節(jié)點2想要連接的對方的節(jié)點的名稱是【rabbit@support】十籍,對方則會按照【rabbit@support】的全名在本地進行節(jié)點搜索
??③ 如果節(jié)點1的主機名稱為localhost,那即使在節(jié)點2的hosts配置了【support - 目標ip】的映射關系唇礁,在節(jié)點1也無法搜索到【rabbit@support】這個節(jié)點勾栗,因為節(jié)點1的真實節(jié)點名稱是【rabbit@localhost】

??【節(jié)點操作】:
刪除集群中的節(jié)點:
①進入待刪除節(jié)點容器
②停止節(jié)點 rabbitmqctl stop_app
③進入主節(jié)點容器刪除待刪除節(jié)點 rabbitmqctl forget_cluster_node node_name

增加集群中的節(jié)點:
①進入待增加節(jié)點容器
②清除數(shù)據(jù) rabbitmqctl reset
③加入集群 rabbitmqctl join_cluster 主節(jié)點名稱
④啟動節(jié)點 rabbitmqctl start_app

(三)、部署Haproxy

??第三、四步的目的是創(chuàng)建主備haproxy和主備對應的監(jiān)測kp,重點依舊是網(wǎng)絡IP配置及VIP創(chuàng)建壁晒。
??ha安裝沒什么好說的。kp裝在宿主機界牡、單獨容器或ha容器都可以,只不過如果要裝在ha容器或單獨容器內(nèi)要用host網(wǎng)絡模式且容器運行的時候加- -privileged參數(shù)吏奸,否則對VIP有影響欢揖;如果kp是裝在宿主機上陶耍,ha用什么網(wǎng)絡模式都可以奋蔚,kp只是一個全端口轉發(fā)。
??建議將kp裝在ha容器內(nèi)烈钞,方便通過腳本監(jiān)控ha的存活狀態(tài)泊碑。

??1.編輯haproxy配置文件如下:

mkdir /home/haproxy
vi /home/haproxy/haproxy.cfg
global
  daemon
  maxconn 10000
  #日志輸出配置,所有日志都記錄在本機毯欣,以local0的日志級別(系統(tǒng)不可用)輸出
  #local0~local7
  # emerg 0-系統(tǒng)不可用      alert 1-必須馬上采取行動的事件
  # crit 2-關鍵的事件       err 3-錯誤事件
  # warning 4-警告事件      notice 5-普通但重要的事件
  # info 6-有用的信息       debug 7-調試信息
 log 127.0.0.1 local0 info

defaults
  mode http
  #應用全局的日志配置
  log global
  #超時配置
  timeout connect 5000ms
  timeout client 5000ms
  timeout server 5000ms
  timeout check 2000ms

#負載均衡的名字(自定義)
#監(jiān)聽5666端口并轉發(fā)到rabbitmq服務
listen rabbitmq_cluster
  bind 0.0.0.0:5666#對外提供的虛擬的端口
  option tcplog
  mode tcp
  #負載均衡算法為輪詢
  balance roundrobin
  #對后端服務器的健康狀況檢查間隔為2000毫秒馒过,
  #連續(xù)2次健康檢查成功,則認為是有效的酗钞,連續(xù)3次健康檢查失敗腹忽,則認為服務器宕機
  server rabbit1 172.16.22.72:5672 check inter 5000ms rise 2 fall 3
  server rabbit2 172.16.22.59:5672 check inter 5000ms rise 2 fall 3

#haproxy的客戶頁面
listen http_front 
  bind 0.0.0.0:25666
  stats uri /haproxy #頁面地址
  #頁面的用戶名和密碼,建議主備設為不同砚作,方便確定搶占到VIP的服務器是主機還是備機
  stats auth root:ruijie 
  stats admin if TRUE #管理界面窘奏,成功登陸后可通過webui管理節(jié)點

#rabbit管理頁面,監(jiān)聽15666端口轉發(fā)到rabbitmq的客戶端
listen rabbitmq_admin 
  bind 0.0.0.0:15666
  server rabbit1 172.16.22.72:15672 check inter 5000ms rise 2 fall 3
  server rabbit2 172.16.22.59:15672 check inter 5000ms rise 2 fall 3

??2.創(chuàng)建haproxy容器
??這里采用host模式進行創(chuàng)建葫录,使用宿主機的網(wǎng)卡着裹,否則KP創(chuàng)建的VIP是容器內(nèi)VIP而不是容器外VIP

#-v 中的參數(shù):ro表示read only,宿主文件為只讀米同。如果不加此參數(shù)默認為rw骇扇,即允許容器對宿主文件的讀寫
#一定要添加--privileged參數(shù),使用該參數(shù),container內(nèi)的root擁有真正的root權限面粮。
#否則少孝,container內(nèi)的root只是外部的一個普通用戶權限(無法創(chuàng)建網(wǎng)卡)
docker run -d --name cluster-rabbit-haproxy --privileged --net host -v /home/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy

??3.在備機上以同樣的配置和命令創(chuàng)建一臺備份haproxy

(四)、安裝keepalived

??這里采用的方式是將kp安裝在haproxy容器內(nèi)

1.進入haproxy容器

docker exec -it cluster-rabbit-haproxy /bin/bash

2.更新熬苍,安裝keepalived

apt-get update
apt-get install keepalived

3.安裝ifconfig稍走,安裝ping,安裝vim,安裝ps

apt-get install net-tools
apt-get install iputils-ping
apt-get install vim
apt-get install procps

4.創(chuàng)建kp配置文件

vi /etc/keepalived/keepalived.conf
#keepalived配置文件
global_defs {
    router_id NodeA                 #路由ID, 主備的ID不能相同
    notification_email {
        xxx@xxx.com
    }
    notification_email_from xxx@xxx.com
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    vrrp_skip_check_adv_addr
    #在keepalived的服務器上配合使用nginx或haproxy時钱磅,需要把這一項注掉梦裂,否則VIP ping不通,80端口也無法正常訪問
    # vrrp_strict 
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

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

vrrp_instance VI_1 {
        state MASTER #Master為主機盖淡,備機設為BACKUP
        interface ens160        #指定網(wǎng)卡(宿主機真實網(wǎng)卡年柠,ip a查看)
        virtual_router_id 1
        priority 100            #優(yōu)先級,BACKUP機器上的優(yōu)先級要小于這個值
        advert_int 1            #設置主備之間的檢查時間褪迟,單位為s
        authentication {        #定義驗證類型和密碼冗恨,主備需相同
                auth_type PASS
                auth_pass ruijie
        }
        track_script {
                chk_haproxy     #ha存活監(jiān)控腳本
        }
        virtual_ipaddress {     #VIP地址,可為多個味赃。如果有需要可以部署雙機雙VIP
           172.16.22.240
        }
}

??【補充】關于雙機雙VIP(參考@dloux_zc)
??A B 雙機掀抹, 正常情況下A綁定vip1, B綁定vip2;頂層通過dns解析將不同的域名分別指向其中一個vip, 以充分利用服務器資源心俗;
??在發(fā)生故障時傲武,A或B上同時綁定兩個VIP。
??在大流量的情況下不建議這么用城榛,如果AB 都接近滿載揪利,一旦發(fā)生故障,其中一臺的流量全部導到另一臺狠持,可能很快將另一臺服務器也壓崩疟位。
??僅作測試及小流量情況又不想浪費備機資源的情況下使用。

??5.配置監(jiān)控腳本

vi /etc/keepalived/check_haproxy.sh
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
        haproxy -f /usr/local/etc/haproxy/haproxy.cfg
fi
sleep 2
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
        #service keepalived stop
        /etc/init.d/keepalived stop
fi

??6.啟動

service keepalived start

??7.查看配置是否成功

ip a

??使用的網(wǎng)卡出現(xiàn)虛擬ip喘垂,則為配置成功


image

??注:ha容器重啟之后kp不會自動重啟

??至此甜刻,高可用的MQ集群已經(jīng)搭建完畢,對外暴露5666端口進行MQ通信正勒,15666端口進行MQ可視化管理得院,ip:25666/haproxy地址進行ha管理

(五)、配置鏡像隊列(可選)

??增加一條策略即可

image

??Name為自定義名稱昭齐;Pattern為正則匹配尿招,^為匹配全部;Definition為具體策略與規(guī)則阱驾,ha-mode配置高可用模式就谜,all為全部
image

??隊列只能定義在一個節(jié)點上,普通模式隊列僅存在于一個節(jié)點里覆,鏡像模式隊列存在于所有節(jié)點丧荐,+1表示額外存在的隊列數(shù)。如果是+2就表示在另外兩個節(jié)點也存在此隊列喧枷,即存在另外兩個節(jié)點
image

(六)虹统、測試

??訪問haproxy的管理頁面: http://172.16.22.240:25666/haproxy
??連接rabbitmq 的5666端口并發(fā)送數(shù)據(jù)弓坞,可以在此頁面,對每次的請求轉發(fā)進行監(jiān)控

image

??訪問rabbitmq的客戶端: http://172.16.22.240:15666
??該頁面為ha對mq集群的輪詢訪問
image

(七)车荔、連接異常的問題處理

參考: https://www.cnblogs.com/xishuai/p/rabbitmq-and-haproxy-channel-shutdown-connection-error.html

??SpringBoot連接集群可能會有 Channel shutdown: connection error 連接錯誤的問題渡冻,
報錯信息如下:

2019-11-18 16:55:23 INFO o.s.a.r.l.SimpleMessageListenerContainer: Restarting Consumer@7925e772: tags=[[amq.ctag-NKT1PBwEVFNlR6zlAklF4A, amq.ctag-QHdxvp2TeHV-7d26AonMPA]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@172.16.22.240:5666/AS_System_Event,2), conn: Proxy@fe156f4 Shared Rabbit Connection: SimpleConnection@bb21063 [delegate=amqp://guest@172.16.22.240:5666/AS_System_Event, localPort= 61176], acknowledgeMode=MANUAL local queue size=0
2019-11-18 16:55:23 INFO       o.s.a.r.c.CachingConnectionFactory: Attempting to connect to: [172.16.22.240:5666]
2019-11-18 16:55:23 INFO       o.s.a.r.c.CachingConnectionFactory: Created new connection: connectionFactory#68c4a860:1/SimpleConnection@f36276b [delegate=amqp://guest@172.16.22.240:5666/AS_System_Event, localPort= 61190]
2019-11-18 16:55:27 ERROR      o.s.a.r.c.CachingConnectionFactory: Channel shutdown: connection error

??從紅框可以看得出來,springboot一直在重復【重啟消費者——連接服務端——創(chuàng)建新連接——連接異秤潜悖】族吻,而綠框則為輪詢請求的兩個服務端。參考鏈接文章確定問題為客戶端連接超時:

??為什么會出現(xiàn)此問題呢珠增?因為 HAProxy 配置了客戶端連接超時參數(shù) timeout client ms超歌,如果客戶端連接超過配置的此參數(shù),那么 HAProxy 將會刪除這個客戶端連接蒂教。
??RabbitMQ 客戶端使用永久連接到代理巍举,從不超時,那為什么還會出現(xiàn)問題凝垛?因為如果 RabbitMQ 在一段時間內(nèi)處于非活動狀態(tài)懊悯,那么 HAProxy 將自動關閉連接

image

引用原文:

image

說了那么多,我們該怎么解決此問題呢苔严?
兩種方案:
① 修改系統(tǒng)的tcp_keepalive_time配置定枷,間隔時間低于 HAProxy 配置的timeout client超時時間(因為有可能影響其他系統(tǒng)服務孤澎,不推薦)届氢。
② 修改 HAProxy 中的timeout client超時時間,配置大于系統(tǒng)的tcp_keepalive_time間隔時間(推薦)覆旭。因為系統(tǒng)tcp_keepalive_time發(fā)送TCP keepalive數(shù)據(jù)包間隔時間是 2 個小時退子,所以,我們將 HAProxy 中的timeout client超時時間型将,設置為 3 個小時

配置文件完整示例:

global
  daemon
  ...

defaults
  ...

listen rabbitmq_cluster
   bind 0.0.0.0:5666
  option tcplog
  timeout client  3h
  timeout server  3h
  mode tcp
  balance roundrobin
  server rabbit1 172.16.22.72:5672 check inter 5000ms rise 2 fall 3
  server rabbit2 172.16.22.59:5672 check inter 5000ms rise 2 fall 3

listen http_front 
  ...

listen rabbitmq_admin 
  ...

??重新運行 HAProxy寂祥,系統(tǒng)正常運行無異常

參考:
https://blog.csdn.net/qq_21108311/article/details/82973763#commentBox
https://www.cnblogs.com/CaesarLinsa/p/11037613.html
https://blog.csdn.net/kevin3101/article/details/86579311

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市七兜,隨后出現(xiàn)的幾起案子丸凭,更是在濱河造成了極大的恐慌,老刑警劉巖腕铸,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惜犀,死亡現(xiàn)場離奇詭異,居然都是意外死亡狠裹,警方通過查閱死者的電腦和手機虽界,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涛菠,“玉大人莉御,你說我怎么就攤上這事撇吞。” “怎么了礁叔?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵牍颈,是天一觀的道長。 經(jīng)常有香客問我琅关,道長颂砸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任死姚,我火速辦了婚禮人乓,結果婚禮上,老公的妹妹穿的比我還像新娘都毒。我一直安慰自己色罚,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布账劲。 她就那樣靜靜地躺著戳护,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瀑焦。 梳的紋絲不亂的頭發(fā)上腌且,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音榛瓮,去河邊找鬼铺董。 笑死,一個胖子當著我的面吹牛禀晓,可吹牛的內(nèi)容都是我干的精续。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼粹懒,長吁一口氣:“原來是場噩夢啊……” “哼重付!你這毒婦竟也來了?” 一聲冷哼從身側響起凫乖,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤确垫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后帽芽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體删掀,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年嚣镜,在試婚紗的時候發(fā)現(xiàn)自己被綠了爬迟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡菊匿,死狀恐怖付呕,靈堂內(nèi)的尸體忽然破棺而出计福,到底是詐尸還是另有隱情,我是刑警寧澤徽职,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布象颖,位于F島的核電站,受9級特大地震影響姆钉,放射性物質發(fā)生泄漏说订。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一潮瓶、第九天 我趴在偏房一處隱蔽的房頂上張望陶冷。 院中可真熱鬧,春花似錦毯辅、人聲如沸埂伦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沾谜。三九已至,卻和暖如春胀莹,著一層夾襖步出監(jiān)牢的瞬間基跑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工描焰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媳否,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓栈顷,卻偏偏與公主長得像逆日,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子萄凤,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348