本文為多宿主搭建徒溪,單機搭建可參考下方文章
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)
(零)贮喧、架構圖
(一)、創(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
??【補充】:
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喘垂,則為配置成功
??注:ha容器重啟之后kp不會自動重啟
??至此甜刻,高可用的MQ集群已經(jīng)搭建完畢,對外暴露5666端口進行MQ通信正勒,15666端口進行MQ可視化管理得院,ip:25666/haproxy地址進行ha管理
(五)、配置鏡像隊列(可選)
??增加一條策略即可
??Name為自定義名稱昭齐;Pattern為正則匹配尿招,^為匹配全部;Definition為具體策略與規(guī)則阱驾,ha-mode配置高可用模式就谜,all為全部
??隊列只能定義在一個節(jié)點上,普通模式隊列僅存在于一個節(jié)點里覆,鏡像模式隊列存在于所有節(jié)點丧荐,+1表示額外存在的隊列數(shù)。如果是+2就表示在另外兩個節(jié)點也存在此隊列喧枷,即存在另外兩個節(jié)點
(六)虹统、測試
??訪問haproxy的管理頁面: http://172.16.22.240:25666/haproxy
??連接rabbitmq 的5666端口并發(fā)送數(shù)據(jù)弓坞,可以在此頁面,對每次的請求轉發(fā)進行監(jiān)控
??訪問rabbitmq的客戶端: http://172.16.22.240:15666
??該頁面為ha對mq集群的輪詢訪問
(七)车荔、連接異常的問題處理
參考: 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 將自動關閉連接
引用原文:
說了那么多,我們該怎么解決此問題呢苔严?
兩種方案:
① 修改系統(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