運(yùn)用.net core中實例講解RabbitMQ高可用集群構(gòu)建
一、集群架構(gòu)簡介
當(dāng)單臺 RabbitMQ 服務(wù)器的處理消息的能力達(dá)到瓶頸時,此時可以通過 RabbitMQ 集群來進(jìn)行擴(kuò)展,從而達(dá)到提升吞吐量的目的。RabbitMQ 集群是一個或多個節(jié)點的邏輯分組,集群中的每個節(jié)點都是對等的,每個節(jié)點共享所有的用戶,虛擬主機(jī),隊列,交換器,綁定關(guān)系,運(yùn)行時參數(shù)和其他分布式狀態(tài)等信息。一個高可用,負(fù)載均衡的 RabbitMQ 集群架構(gòu)應(yīng)類似下圖:
解析說明:
最下面層是RabbitMQ的集群,沒有ha鏡像時是普通集群,普通集群的缺點是掛了一個機(jī)器,以這個機(jī)器為根的隊列就無法使用了(一個隊列的數(shù)據(jù)只會存在一個節(jié)點),無法實現(xiàn)高可用。
所以把隊列變成鏡像隊列,這樣每個節(jié)點都會有一份完整的數(shù)據(jù),有節(jié)點掛了也不影響使用,實現(xiàn)了高可用,但RabbitMQ集群本身沒有實現(xiàn)負(fù)載均衡,也就是說對于一個三節(jié)點的集群,
每個節(jié)點的負(fù)載可能都是不相同的。
HAProxy層的作用就是為了實現(xiàn)RabbitMQ集群的負(fù)載均衡,但一個節(jié)點的話顯然也不能高可用,所以需要兩個HAProxy實現(xiàn)HaProxy的高可用,但沒法實現(xiàn)自動的故障轉(zhuǎn)移,就是HAProxy1掛了,
需要手動把ip地址改成HAProxy2的。
所以需要用到KeepAlived,它通常由一主一備兩個節(jié)點組成,同一時間內(nèi)只有主節(jié)點會提供對外服務(wù),并同時提供一個虛擬的 IP 地址 (Virtual Internet Protocol Address ,簡稱 VIP),可以避免暴露真實ip 。 如果主節(jié)點故障,那么備份節(jié)點會自動接管 VIP 并成為新的主節(jié)點 ,直到原有的主節(jié)點恢復(fù)。
生產(chǎn)環(huán)境架構(gòu)應(yīng)該為:
機(jī)器1:RabbitMQ1,機(jī)器2:RabbitMQ2,機(jī)器3:RabbitMQ3,機(jī)器4:HAProxy+keeplived(主),機(jī)器5(HAProxy+keeplived(備)。
這里資源原因只有3臺機(jī)器,所以搭建架構(gòu)為:
172.16.2.84(rabbit1) | RabbitMQ1,HAProxy+keeplived(主) |
172.16.2.85(rabbit2) | RabbitMQ2,HAProxy+keeplived(備) |
172.16.2.86(rabbit3) | RabbitMQ3 |
二、普通集群搭建
2.1 各個節(jié)點分別安裝RabbitMQ
這里前面的章節(jié)功能使用是用的docker安裝,這里集群不用docker,因為docker安裝會有很多的映射,很容易擾亂,裝有docker的rabbitmq的,需要先把docker停掉。
這里準(zhǔn)備了3臺機(jī)器,172.16.2.84(rabbit1),172.16.2.85(rabbit2),172.16.2.86(rabbit3),為了避免混淆,下面都會用rabbit1,rabbit2,rabbit3稱呼。
rabbit1,rabbit2,rabbit3都執(zhí)行一遍下面的安裝。
1)安裝前,先修改hostname,因為rabbitmq集群通訊需要用hostname
rabbit1機(jī)器執(zhí)行
hostnamectl set-hostname rabbit1 --static
rabbit2機(jī)器執(zhí)行
hostnamectl set-hostname rabbit2 --static
rabbit3機(jī)器執(zhí)行
hostnamectl set-hostname rabbit3 --static
rabbit1,rabbit2,rabbit3執(zhí)行同樣操作
#修改hosts,因為rabbitmq通訊要通過hostname
vi /etc/hosts
2)把ip對應(yīng)hostname添加到后面
172.16.2.84 rabbit1
172.16.2.85 rabbit2
172.16.2.86 rabbit3
# 重啟網(wǎng)絡(luò) systemctl restart network # 重啟機(jī)器 init 6
3)安裝Erlang
#第一步 運(yùn)行package cloud提供的erlang安裝腳本
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
#第二步 安裝erlang
yum install erlang
#第三步 查看erlang版本號,在命令行直接輸入erl
erl
4)安裝RabbitMQ
#第一步 先導(dǎo)入兩個key
rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
rpm --import https://packagecloud.io/gpg.key
#第二步 運(yùn)行package cloud提供的rabbitmq安裝腳本
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
#第三步 下載rabbit安裝文件
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.5/rabbitmq-server-3.9.5-1.el8.noarch.rpm
#第四步
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
#第五步 rabbitMQ依賴
yum -y install epel-release
yum -y install socat
#第六步 安裝
rpm -ivh rabbitmq-server-3.9.5-1.el8.noarch.rpm
#第七步 啟用管理平臺插件,啟用插件后,可以可視化管理RabbitMQ
rabbitmq-plugins enable rabbitmq_management
#第八步 啟動應(yīng)用
systemctl start rabbitmq-server
上面rabbitmq的版本號安裝文件地址:https://github.com/rabbitmq/rabbitmq-server/releases/
5)設(shè)置訪問權(quán)限
#創(chuàng)建管理員賬戶 rabbitmqctl add_user admin 123456 #設(shè)置注冊的賬戶為管理員 rabbitmqctl set_user_tags admin administrator #授權(quán)遠(yuǎn)程訪問 rabbitmqctl set_permissions -p / admin "." "." ".*" #重啟服務(wù) systemctl restart rabbitmq-server
注意這里關(guān)了防火墻,如果開啟防火墻的話,需要把15672端口開放出來
#查看防火墻狀態(tài) systemctl status firewalld #關(guān)閉防火墻 systemctl stop firewalld
到這里,3臺機(jī)器都安裝好了RabbitMQ。
2.2 把節(jié)點加入集群
1)停止服務(wù)rabbit2,rabbit3
#停止全部服務(wù) systemctl stop rabbitmq-server
2)拷貝cookie
將rabbit1上的.erlang.cookie文件拷貝到其他兩臺主機(jī)上。該 cookie 文件相當(dāng)于密鑰令牌,集群中的 RabbitMQ 節(jié)點需要通過交換密鑰令牌以獲得相互認(rèn)證,因此處于同一集群的所有節(jié)點需要具有相同的密鑰令牌,否則在搭建過程中會出現(xiàn) Authentication Fail 錯誤,只要保證這3臺機(jī)器中的.erlang.cookie內(nèi)的密鑰字符串一致即可,這里把rabbit1的密鑰復(fù)制到rabbit2,rabbit3。
3個機(jī)器都給.erlang.cookie 400權(quán)限。
#給600權(quán)限 chmod 600 /var/lib/rabbitmq/.erlang.cookie
rabbit1機(jī)器
#編輯文件
vi /var/lib/rabbitmq/.erlang.cookie
把內(nèi)容復(fù)制出來,修改rabbit2,rabbit3這個文件的值為這個。
啟動服務(wù)
#開啟全部服務(wù) systemctl start rabbitmq-server
3)集群搭建
RabbitMQ 集群的搭建需要選擇其中任意一個節(jié)點為基準(zhǔn),將其它節(jié)點逐步加入。這里我們以 rabbit1為基準(zhǔn)節(jié)點,將 rabbit2 和 rabbit3 加入集群。在 rabbit2和 rabbit3上執(zhí)行以下命令:
# 1.停止服務(wù) rabbitmqctl stop_app # 2.重置狀態(tài)(需要更改節(jié)點類型的時候執(zhí)行,首次不需要執(zhí)行,除非你節(jié)點是以disk加入集群的) rabbitmqctl reset # 3.節(jié)點加入 #rabbitmqctl join_cluster --ram rabbit@rabbit1 rabbitmqctl join_cluster rabbit@rabbit1 # 4.啟動服務(wù) rabbitmqctl start_app
join_cluster
命令有一個可選的參數(shù) --ram
,該參數(shù)代表新加入的節(jié)點是內(nèi)存節(jié)點,默認(rèn)是磁盤節(jié)點。如果是內(nèi)存節(jié)點,則所有的隊列、交換器、綁定關(guān)系、用戶、訪問權(quán)限和 vhost 的元數(shù)據(jù)都將存儲在內(nèi)存中,如果是磁盤節(jié)點,則存儲在磁盤中。內(nèi)存節(jié)點可以有更高的性能,但其重啟后所有配置信息都會丟失,因此RabbitMQ 要求在集群中至少有一個磁盤節(jié)點,其他節(jié)點可以是內(nèi)存節(jié)點,大多數(shù)情況下RabbitMQ 的性能都是夠用的,可以采用默認(rèn)的磁盤節(jié)點的形式。
另外,如果節(jié)點以磁盤節(jié)點的形式加入,則需要先使用reset
命令進(jìn)行重置,然后才能加入現(xiàn)有群集,重置節(jié)點會刪除該節(jié)點上存在的所有的歷史資源和數(shù)據(jù)。采用內(nèi)存節(jié)點的形式加入時可以略過reset
這一步,因為內(nèi)存上的數(shù)據(jù)本身就不是持久化的。
操作上面的,一個普通集群就搭建成功了,打開rabbit管理界面(隨便打開一個都是一樣的)。
2.3 代碼演示普通集群的問題
普通集群中, 第一次創(chuàng)建隊列時,會隨機(jī)選一個節(jié)點作為根節(jié)點,這個節(jié)點會存儲隊列的信息(交互機(jī),路由,隊列名等)和隊列的數(shù)據(jù),其它兩個節(jié)點只會同步根節(jié)點的元信息(交換機(jī),路由,隊列名)等,
但不會存儲隊列的數(shù)據(jù),他們是通過元信息找到根節(jié)點讀寫消息。
例如集群選擇了rabbit2作為根節(jié)點,那么數(shù)據(jù)存儲在rabbit2,rabbit1和rabbit3是沒有數(shù)據(jù)的,那么如果rabbit2宕機(jī)了,隊列里面的數(shù)據(jù)就取不到了。
代碼演示,.NetCore5.0讀取集群連接代碼。
/// <summary> /// 獲取集群連接對象 /// </summary> /// <returns></returns> public static IConnection GetClusterConnection() { var factory = new ConnectionFactory { UserName = "admin",//賬戶 Password = "123456",//密碼 VirtualHost = "/" //虛擬機(jī) }; List<AmqpTcpEndpoint> list = new List<AmqpTcpEndpoint>() { new AmqpTcpEndpoint(){HostName="172.16.2.84",Port=5672}, new AmqpTcpEndpoint(){HostName="172.16.2.85",Port=5672}, new AmqpTcpEndpoint(){HostName="172.16.2.86",Port=5672} }; return factory.CreateConnection(list); }
生產(chǎn)者代碼:
/// <summary> /// 工作隊列模式 /// </summary> public static void WorkerSendMsg() { string queueName = "worker_order";//隊列名 //創(chuàng)建連接 using (var connection = RabbitMQHelper.GetClusterConnection()) { //創(chuàng)建信道 using (var channel = connection.CreateModel()) { //創(chuàng)建隊列 channel.QueueDeclare(queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); IBasicProperties properties = channel.CreateBasicProperties(); properties.Persistent = true; //消息持久化 for ( var i=0;i<10;i++) { string message = $"Hello RabbitMQ MessageHello,{i+1}"; var body = Encoding.UTF8.GetBytes(message); //發(fā)送消息到rabbitmq channel.BasicPublish(exchange: "", routingKey: queueName, mandatory: false, basicProperties: properties, body); Console.WriteLine($"發(fā)送消息到隊列:{queueName},內(nèi)容:{message}"); } } } }
執(zhí)行:
查看RabbitMQ管理界面
RabbitMQ選擇了rabbit3作為根節(jié)點,現(xiàn)在試一下停止rabbit3節(jié)點
#停止服務(wù) rabbitmqctl stop_app
發(fā)現(xiàn)隊列不可用了,啟動rabbit3,再試一下停止rabbit2
發(fā)現(xiàn)隊列正常,試下消費(fèi)數(shù)據(jù):
public static void WorkerConsumer() { string queueName = "worker_order"; var connection = RabbitMQHelper.GetClusterConnection(); { //創(chuàng)建信道 var channel = connection.CreateModel(); { //創(chuàng)建隊列 channel.QueueDeclare(queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); ///prefetchCount:1來告知RabbitMQ,不要同時給一個消費(fèi)者推送多于 N 個消息,也確保了消費(fèi)速度和性能 ///global:是否設(shè)為全局的 ///prefetchSize:單條消息大小,通常設(shè)0,表示不做限制 //是autoAck=false才會有效 channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: true); int i = 1; int index = new Random().Next(10); consumer.Received += (model, ea) => { //處理業(yè)務(wù) var message = Encoding.UTF8.GetString(ea.Body.ToArray()); Console.WriteLine($"{i},消費(fèi)者:{index},隊列{queueName}消費(fèi)消息長度:{message.Length}"); Thread.Sleep(1000); channel.BasicAck(ea.DeliveryTag, false); //消息ack確認(rèn),告訴mq這條隊列處理完,可以從mq刪除了 i++; }; channel.BasicConsume(queueName, autoAck: false, consumer); } } }
如果根節(jié)點掛了,再往集群發(fā)送數(shù)據(jù),RabbitMQ又會從其余的選一個作為根節(jié)點,就可能的情況是,多個節(jié)點都存有不同隊列的數(shù)據(jù)。
到這里,可以看到普通集群并不可以高可用, 根節(jié)點掛了,在這個節(jié)點上的隊列也不可用了。但三個節(jié)點都沒問題的時候,可以提高并發(fā)和隊列的負(fù)載。
要實現(xiàn)高可用,就要用到了鏡像集群。
三、鏡像集群
鏡像集群,在每個節(jié)點上都同步一份鏡像數(shù)據(jù),相當(dāng)于每個節(jié)點都有一份完整的數(shù)據(jù),這樣有節(jié)點宕機(jī)了,還能正常提供RabbitMQ服務(wù)。
變鏡像集群很簡單,在上面普通集群的基礎(chǔ)上,在任意一個節(jié)點下執(zhí)行
#把集群變成鏡像集群 rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
執(zhí)行完,看回隊列,多了ha標(biāo)識。
四、HAProxy環(huán)境搭建。
1)下載
HAProxy 官方下載地址為:https://www.haproxy.org/,如果這個網(wǎng)站無法訪問,也可以從https://src.fedoraproject.org/repo/pkgs/haproxy/上進(jìn)行下載。
#下載haproxy wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.3.tar.gz
解壓
#解壓 tar xf haproxy-2.4.3.tar.gz
2)編譯
安裝gcc
yum install gcc
進(jìn)入解壓后根目錄,執(zhí)行下面的編譯命令:
#進(jìn)入haproxy-2.4.3目錄后執(zhí)行 make TARGET=linux-glibc PREFIX=/usr/app/haproxy-2.4.3 make install PREFIX=/usr/app/haproxy-2.4.3
3)配置環(huán)境變量
#編輯文件 vi /etc/profile #把這兩項加上 export HAPROXY_HOME=/usr/app/haproxy-2.4.3 export PATH=$PATH:$HAPROXY_HOME/sbin
使得配置的環(huán)境變量立即生效:
source /etc/profile
4)負(fù)載均衡配置
新建配置文件haproxy.cfg,這里我新建的位置為:/etc/haproxy/haproxy.cfg,文件內(nèi)容如下:
global
# 日志輸出配置、所有日志都記錄在本機(jī),通過 local0 進(jìn)行輸出
log 127.0.0.1 local0 info
# 最大連接數(shù)
maxconn 4096
# 改變當(dāng)前的工作目錄
chroot /usr/app/haproxy-2.4.3
# 以指定的 UID 運(yùn)行 haproxy 進(jìn)程
uid 99
# 以指定的 GID 運(yùn)行 haproxy 進(jìn)程
gid 99
# 以守護(hù)進(jìn)行的方式運(yùn)行
daemon
# 當(dāng)前進(jìn)程的 pid 文件存放位置
pidfile /usr/app/haproxy-2.4.3/haproxy.pid
# 默認(rèn)配置
defaults
# 應(yīng)用全局的日志配置
log global
# 使用4層代理模式,7層代理模式則為"http"
mode tcp
# 日志類別
option tcplog
# 不記錄健康檢查的日志信息
option dontlognull
# 3次失敗則認(rèn)為服務(wù)不可用
retries 3
# 每個進(jìn)程可用的最大連接數(shù)
maxconn 2000
# 連接超時
timeout connect 5s
# 客戶端超時
timeout client 120s
# 服務(wù)端超時
timeout server 120s
# 綁定配置
listen rabbitmq_cluster
bind :5671
# 配置TCP模式
mode tcp
# 采用加權(quán)輪詢的機(jī)制進(jìn)行負(fù)載均衡
balance roundrobin
# RabbitMQ 集群節(jié)點配置
server rabbit1 rabbit1:5672 check inter 5000 rise 2 fall 3 weight 1
server rabbit2 rabbit2:5672 check inter 5000 rise 2 fall 3 weight 1
server rabbit3 rabbit3:5672 check inter 5000 rise 2 fall 3 weight 1
# 配置監(jiān)控頁面
listen monitor
bind :8100
mode http
option httplog
stats enable
stats uri /stats
stats refresh 5s
上傳上去的,記得打開看一下?lián)Q行符有沒有出行這些符號,如果有要刪掉,不然會報錯。
負(fù)載均衡的主要配置在listen rabbitmq_cluster
下,這里指定負(fù)載均衡的方式為加權(quán)輪詢,同時定義好健康檢查機(jī)制:
server rabbit1 rabbit1:5672 check inter 5000 rise 2 fall 3 weight 1
以上配置代表對地址為 rabbit1:5672 的 rabbit1 節(jié)點每隔 5 秒進(jìn)行一次健康檢查,如果連續(xù)兩次的檢查結(jié)果都是正常,則認(rèn)為該節(jié)點可用,此時可以將客戶端的請求輪詢到該節(jié)點上;如果連續(xù) 3 次的檢查結(jié)果都不正常,則認(rèn)為該節(jié)點不可用。weight 用于指定節(jié)點在輪詢過程中的權(quán)重。
5)啟動服務(wù)
haproxy -f /etc/haproxy/haproxy.cfg
啟動后可以在監(jiān)控頁面進(jìn)行查看,端口為設(shè)置的 8100,完整地址為:http://172.16.2.84:8100/stats,頁面情況如下:
所有節(jié)點都為綠色,代表節(jié)點健康。此時證明 HAProxy 搭建成功,并已經(jīng)對 RabbitMQ 集群進(jìn)行監(jiān)控。
這里已經(jīng)實現(xiàn)了RabbitMQ的負(fù)載均衡了,代碼怎么通過Haproxy連接Rabbit集群呢,因為上面配置Haproxy暴露的端口是5671,所以Ip是Haproxy的ip:5671。
連接代碼,可以通過haproxy1 或haproxy2都可以:
public static IConnection GetConnection() { ConnectionFactory factory = new ConnectionFactory { HostName = "172.16.2.84",//haproxy ip Port = 5671,//haproxy 端口 UserName = "admin",//賬號 Password = "123456",//密碼 VirtualHost = "/" //虛擬主機(jī) }; return factory.CreateConnection(); }
五、KeepAlived 環(huán)境搭建
接著就可以搭建 Keepalived 來解決 HAProxy 故障轉(zhuǎn)移的問題。這里我在 rabbit1 和 rabbit2 上安裝 KeepAlived ,兩臺主機(jī)上的搭建的步驟完全相同,只是部分配置略有不同,具體如下:
官網(wǎng):https://www.keepalived.org
1)安裝
yum install -y keepalived
2)修改配置文件
安裝了keepalived后,配置文件生成在/etc/keepalived/keepalived.conf
這里先對keepalived1上keepalived.conf配置文件進(jìn)行修改,完整內(nèi)容如下:
global_defs { # 路由id,主備節(jié)點不能相同 router_id node1 } # 自定義監(jiān)控腳本 vrrp_script chk_haproxy { # 腳本位置 script "/etc/keepalived/haproxy_check.sh" # 腳本執(zhí)行的時間間隔 interval 5 weight 10 } vrrp_instance VI_1 { # Keepalived的角色,MASTER 表示主節(jié)點,BACKUP 表示備份節(jié)點 state MASTER # 指定監(jiān)測的網(wǎng)卡,可以使用 ip addr 進(jìn)行查看 interface ens33 # 虛擬路由的id,主備節(jié)點需要設(shè)置為相同 virtual_router_id 1 # 優(yōu)先級,主節(jié)點的優(yōu)先級需要設(shè)置比備份節(jié)點高 priority 100 # 設(shè)置主備之間的檢查時間,單位為秒 advert_int 1 # 定義驗證類型和密碼 authentication { auth_type PASS auth_pass 123456 } # 調(diào)用上面自定義的監(jiān)控腳本 track_script { chk_haproxy } virtual_ipaddress { # 虛擬IP地址,可以設(shè)置多個 172.16.2.200 } }
以上配置定義了 keepalived1上的 Keepalived 節(jié)點為 MASTER 節(jié)點,并設(shè)置對外提供服務(wù)的虛擬 IP 為 172.16.2.200。此外最主要的是定義了通過haproxy_check.sh
來對 HAProxy 進(jìn)行監(jiān)控,這個腳本需要我們自行創(chuàng)建,內(nèi)容如下:
#!/bin/bash # 判斷haproxy是否已經(jīng)啟動 if [ `ps -C haproxy --no-header | wc -l` -eq 0 ] ; then #如果沒有啟動,則啟動 haproxy -f /etc/haproxy/haproxy.cfg fi #睡眠3秒以便haproxy完全啟動 sleep 3 #如果haproxy還是沒有啟動,此時需要將本機(jī)的keepalived服務(wù)停掉,以便讓VIP自動漂移到另外一臺haproxy if [ `ps -C haproxy --no-header | wc -l` -eq 0 ]; then systemctl stop keepalived fi
創(chuàng)建后為其賦予執(zhí)行權(quán)限:
chmod +x /etc/keepalived/haproxy_check.sh
這個腳本主要用于判斷 HAProxy 服務(wù)是否正常,如果不正常且無法啟動,此時就需要將本機(jī) Keepalived 關(guān)閉,從而讓虛擬 IP 漂移到備份節(jié)點。
備份節(jié)點(keepalived2)的配置與主節(jié)點基本相同,但是需要修改其 state 為 BACKUP;同時其優(yōu)先級 priority 需要比主節(jié)點低。完整配置如下:
global_defs { # 路由id,主備節(jié)點不能相同 router_id node2 } vrrp_script chk_haproxy { script "/etc/keepalived/haproxy_check.sh" interval 5 weight 10 } vrrp_instance VI_1 { # BACKUP 表示備份節(jié)點 state BACKUP interface ens33 virtual_router_id 1 # 優(yōu)先級,備份節(jié)點要比主節(jié)點低 priority 50 advert_int 1 authentication { auth_type PASS auth_pass 123456 } track_script { chk_haproxy } virtual_ipaddress { 172.16.2.200 } }
haproxy_check.sh文件和keepalived1相同
3)啟動服務(wù)
分別在KeepAlived1和KeepAlived2上啟動KeepAlived服務(wù),命令如下:
systemctl start keepalived
啟動后此時 keepAlived1 為主節(jié)點,可以在keepAlived1 上使用ip a
命令查看到虛擬 IP 的情況:
此時只有 keepAlived1上是存在虛擬 IP 的,而keepAlived2 上是沒有的。
4)驗證故障轉(zhuǎn)移
這里我們驗證一下故障轉(zhuǎn)移,因為按照我們上面的檢測腳本,如果 HAProxy 已經(jīng)停止且無法重啟時 KeepAlived 服務(wù)就會停止,這里我們直接使用以下命令停止 Keepalived1 服務(wù):
systemctl stop keepalived
此時再次使用ip a
分別查看,可以發(fā)現(xiàn) keepalived1上的 VIP 已經(jīng)漂移到 keepalived2上,情況如下:
此時對外服務(wù)的 VIP 依然可用,代表已經(jīng)成功地進(jìn)行了故障轉(zhuǎn)移。至此集群已經(jīng)搭建成功,任何需要發(fā)送或者接受消息的客戶端服務(wù)只需要連接到該 VIP 即可,示例如下:
public static IConnection GetConnection() { ConnectionFactory factory = new ConnectionFactory() { HostName = "172.16.2.200",//vip Port = 5671,//haproxy 端口 UserName = "admin",//賬號 Password = "123456",//密碼 VirtualHost = "/" //虛擬主機(jī) }; return factory.CreateConnection(); }
到此這篇關(guān)于運(yùn)用.net core中實例講解RabbitMQ高可用集群構(gòu)建的文章就介紹到這了,更多相關(guān).net core RabbitMQ集群構(gòu)建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Asp.net生成Excel文件并下載(更新:解決使用迅雷下載頁面而不是文件的問題)
Asp.net生成Excel文件并下載(更新:解決使用迅雷下載頁面而不是文件的問題)2012-01-01Request.QueryString與一般NameValueCollection的區(qū)別
最近在做一個搜索程序的優(yōu)化改進(jìn),將搜索結(jié)果按照查詢的參數(shù)不同進(jìn)行緩存。緩存的Key很自然的就想到了用查詢字符串,而獲取查詢字符串的最簡單方式是通過Request.QueryString.ToString()方法2011-12-12使用ASP.NET 2.0 CSS 控件適配器生成CSS友好的HTML輸出
使用ASP.NET 2.0 CSS 控件適配器生成CSS友好的HTML輸出...2007-03-03MVC使用Controller代替Filter完成登錄驗證(Session校驗)學(xué)習(xí)筆記5
這篇文章主要介紹了MVC使用Controller代替Filter完成登錄驗證即Session校驗,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09