怎么實(shí)現(xiàn)雙機(jī)熱備Nginx高可用呢?

一、背景
在一般的系統(tǒng)架構(gòu)中,往往是采用一臺(tái)Nginx做負(fù)載均衡,這臺(tái)Nginx可能負(fù)責(zé)著轉(zhuǎn)發(fā)多臺(tái)Tomcat的請求。這就有一個(gè)問題,如果這臺(tái)Nginx服務(wù)器掛了,那就等于整個(gè)系統(tǒng)都掛了。
所以就需要引入一種機(jī)制,將Nginx集群化,同時(shí)保證有多臺(tái)Nginx在運(yùn)行,一臺(tái)掛了,另外一臺(tái)還能繼續(xù)提供服務(wù)。要實(shí)現(xiàn)Nginx的高可用,就不得不提LVS+Keepalived。
Lvs+Keepalived:Lvs負(fù)責(zé)將外網(wǎng)請求交由集群中的Nginx進(jìn)行處理;keepalived則監(jiān)控lvs群組,根據(jù)監(jiān)控情況,若lvs群組中的master出現(xiàn)宕機(jī)情況,則將宕機(jī)服務(wù)器從ipvsadm移除掉,即將VIP漂移到backup機(jī)上。實(shí)現(xiàn)了分布式系統(tǒng)高可用。
二、環(huán)境準(zhǔn)備
系統(tǒng):Centos7
MASTER ?192.168.1.124:安裝Lvs+Keepalived
BACKUP 192.168.1.126:安裝Lvs+Keepalived
192.168.1.127:安裝Nginx
192.168.1.128:安裝Nginx
虛擬ip(VIP):192.168.1.110,對外提供服務(wù)的ip,也可稱作浮動(dòng)ip

image.png
三、安裝Nginx
1、參考安裝教程:
https://www.jianshu.com/p/b58b2767a92d
分別為192.168.1.127、192.168.1.128安裝Nginx
2、Nginx配置
假設(shè)我們現(xiàn)在的項(xiàng)目是前后端分離的項(xiàng)目,Nginx負(fù)責(zé)轉(zhuǎn)發(fā)到前端項(xiàng)目上。現(xiàn)在我新建一個(gè)簡單的前端html頁面,放在下面的文件位置,然后由Nginx去訪問(兩臺(tái)Nginx文件位置一樣,只是為了驗(yàn)證訪問的是哪臺(tái)Nginx,html內(nèi)容有些許區(qū)別,)

image.png
在/etc/nginx/conf.d目錄下,修改default.conf,加入以下內(nèi)容
location /demo {
root /root/server/vue/demo/; #項(xiàng)目路徑
index /demo.html;
}
配置完后,重啟Nginx即可
systemctl restart nginx #重啟Nginx
如果安裝配置成功,運(yùn)行后應(yīng)該能訪問到新建的demo.html頁面,我的效果如下。

image.png
四、配置Master主機(jī)(此處我的主機(jī)是:192.168.1.124)
1、前提配置
開放80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
關(guān)閉SELINUX,修改/etc/sysconfig/selinux,永久生效
SELINUX=enforcing 改為 SELINUX=disabled
修改文件關(guān)閉SELINUX需要重啟機(jī)器才能生效,如果不方便重啟,可以臨時(shí)用命令修改,立即生效,但是重啟后就會(huì)失效。所以我們可以先修改文件(但是不立即重啟),然后再用命令執(zhí)行立即生效,這樣等下次有其他需求重啟的時(shí)候,SELINUX關(guān)閉也就永久生效了。
setenforce 0
防火墻開啟vrrp 協(xié)議支持
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
2、安裝Keepalived
執(zhí)行命令安裝
yum -y install keepalived
配置/etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
#notification_email { #email 通知
#[email protected] #設(shè)置報(bào)警郵件地址,可以設(shè)置多個(gè),每行一個(gè)。
#[email protected]
#[email protected]
#}
#notification_email_from [email protected] #設(shè)置郵件的發(fā)送地址
#smtp_server 192.168.200.1 #設(shè)置smtp server地址
#smtp_connect_timeout 30 #設(shè)置連接smtp server的超時(shí)時(shí)間
router_id LVS_DEVEL #表示運(yùn)行keepalived服務(wù)器的一個(gè)標(biāo)識(shí)。發(fā)郵件時(shí)顯示在郵件主題的信息
#vrrp_skip_check_adv_addr
#vrrp_strict
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER #指定keepalived的角色,MASTER表示此主機(jī)是主服務(wù)器,BACKUP表示此主機(jī)是備用服務(wù)器
interface ens33 #網(wǎng)卡名,用ip a命令可以查看
virtual_router_id 51 #虛擬路由標(biāo)識(shí),主備兩個(gè)節(jié)點(diǎn)的設(shè)置必須一樣,以指明各個(gè)節(jié)點(diǎn)屬于同一VRRP組
priority 100 #定義優(yōu)先級(jí),數(shù)字越大,優(yōu)先級(jí)越高,在同一個(gè)vrrp_instance下,MASTER的優(yōu)先級(jí)必須大于BACKUP的優(yōu)先級(jí)
advert_int 1 ##設(shè)定MASTER與BACKUP負(fù)載均衡器之間同步檢查的時(shí)間間隔,單位是秒
authentication { #設(shè)置驗(yàn)證類型和密碼
auth_type PASS #設(shè)置驗(yàn)證類型,主要有PASS和AH兩種
auth_pass 1111 #設(shè)置驗(yàn)證密碼,在同一個(gè)vrrp_instance下,MASTER與BACKUP必須使用相同的密碼才能正常通信
}
virtual_ipaddress { #設(shè)置vip
192.168.1.110 #可以多個(gè)虛擬IP,換行即可
}
}
virtual_server 192.168.1.110 80 { #設(shè)置虛擬服務(wù)器,需要指定虛擬IP地址和服務(wù)端口,IP與端口之間用空格隔開
delay_loop 6 ##健康時(shí)間檢查,單位秒
lb_algo rr #負(fù)載均衡調(diào)度算法wlc|rr,和您將使用的LVS的調(diào)度算法保持原則一致
lb_kind DR #設(shè)置LVS實(shí)現(xiàn)負(fù)載均衡的機(jī)制,有NAT、TUN、DR三個(gè)模式可選
persistence_timeout 50 #會(huì)話保持時(shí)間,單位是秒。這個(gè)選項(xiàng)對動(dòng)態(tài)網(wǎng)頁是非常有用的,為集群系統(tǒng)中的session共享提供了一個(gè)很好的解決方案。
#有了這個(gè)會(huì)話保持功能,用戶的請求會(huì)被一直分發(fā)到某個(gè)服務(wù)節(jié)點(diǎn),直到超過這個(gè)會(huì)話的保持時(shí)間。
#需要注意的是,這個(gè)會(huì)話保持時(shí)間是最大無響應(yīng)超時(shí)時(shí)間,也就是說,用戶在操作動(dòng)態(tài)頁面時(shí),如果50秒內(nèi)沒有執(zhí)行任何操作
#那么接下來的操作會(huì)被分發(fā)到另外的節(jié)點(diǎn),但是如果用戶一直在操作動(dòng)態(tài)頁面,則不受50秒的時(shí)間限制
protocol TCP #指定轉(zhuǎn)發(fā)協(xié)議類型,有TCP和UDP兩種
real_server 192.168.1.127 80 { #真實(shí)服務(wù)器,此處為Nginx服務(wù)器
weight 1 #設(shè)置權(quán)重,數(shù)字越大權(quán)重越高
TCP_CHECK { #設(shè)置檢查方式,可以設(shè)置HTTP_GET | SSL_GET
connect_timeout 3 #超時(shí)時(shí)間,秒。如果在這個(gè)時(shí)間內(nèi)沒有返回,則說明一次監(jiān)測失敗
nb_get_retry 3 #設(shè)置多少次監(jiān)測失敗,就認(rèn)為這個(gè)真實(shí)節(jié)點(diǎn)死掉了
delay_before_retry 3 #重試間隔
}
}
real_server 192.168.1.128 80 { #真實(shí)服務(wù)器,此處為Nginx服務(wù)器
weight 1 #設(shè)置權(quán)重,數(shù)字越大權(quán)重越高
TCP_CHECK { #設(shè)置檢查方式,可以設(shè)置HTTP_GET | SSL_GET | TCP_CHECK
connect_timeout 3 #超時(shí)時(shí)間,秒。如果在這個(gè)時(shí)間內(nèi)沒有返回,則說明一次監(jiān)測失敗
nb_get_retry 3 #設(shè)置多少次監(jiān)測失敗,就認(rèn)為這個(gè)真實(shí)節(jié)點(diǎn)死掉了
delay_before_retry 3 #重試間隔
}
}
}
3、安裝ipvsadm
執(zhí)行命令安裝。安裝ipvsadm在此處只是為了查看LVS的轉(zhuǎn)發(fā)情況
yum -y install ipvsadm
查看lvs狀態(tài)
ipsvadm
五、配置Slave主機(jī)(此處我的主機(jī)是:192.168.1.126)
1、安裝Keepalived
安裝同上Master
配置有些許改變
state MASTER 改為:state BACKUP
priority 100 改小為:priority 99
六、配置兩臺(tái)真實(shí)主機(jī)(此處為兩臺(tái)Nginx)
1、 兩臺(tái)真實(shí)Nginx服務(wù)器上為回環(huán)地址lo:0綁定VIP地址、ARP廣播
新建腳本文件realserver.sh,分別在兩臺(tái)真實(shí)服務(wù)器(192.168.1.127、192.168.1.128)上執(zhí)行
#!/bin/bash
#description: Config realserver
VIP=192.168.1.110
/etc/rc.d/init.d/functions
case "$1" in
start)
/sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
/sbin/route add -host $VIP dev lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo "RealServer Start OK"
;;
stop)
/sbin/ifconfig lo:0 down
/sbin/route del $VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
執(zhí)行
chmod +x realserver.sh #賦予權(quán)限
chmod +x /etc/rc.d/init.d/functions
./realserver.sh start #執(zhí)行
另外這個(gè)腳本的修改重啟后就會(huì)失效,所以我們需要將這個(gè)腳本設(shè)置為開機(jī)自啟動(dòng)。
chmod +x /etc/rc.d/rc.local
修改rc.local
vi /etc/rc.d/rc.local
加入以下文件最后追加以下內(nèi)容即可
/etc/rc.d/init.d/realserver.sh start
realserver.sh啟動(dòng)成功后,可以看到192.168.1.127主機(jī)上的回環(huán)地址已經(jīng)綁定上了VIP。

image.png
七、啟動(dòng)keepalived
啟動(dòng)192.168.1.124、192.168.1.126的keepalived
#啟動(dòng)Keepalived
systemctl start keepalived
設(shè)置開機(jī)自啟動(dòng)
#keepalived設(shè)置開機(jī)啟動(dòng)
systemctl enable keepalived
其他參考命令
#Keepalived 相關(guān)操作命令
#關(guān)閉Keepalived
systemctl stop keepalived
#重啟Keepalived
systemctl restart keepalived
#查看狀態(tài)Keepalived
systemctl status keepalived
在Master主機(jī)上查看vip是否綁定上
ip addr
可以看到Marster:192.168.1.127的ens33網(wǎng)卡上已經(jīng)綁定了Vip

image.png
查看keepalived日志
tail -f /var/log/messages
八、試驗(yàn)
1.正常情況
正常情況下,lvs會(huì)把請求轉(zhuǎn)發(fā)到兩個(gè)nginx服務(wù)上,如下圖

image.png

image.png
2.關(guān)閉一臺(tái)keepalived,模擬一臺(tái)keepalived主機(jī)掛掉。
關(guān)閉master
systemctl stop keepalived
可以看到master192.168.1.124解綁vip,backup接管了vip

Master

BackUp
頁面可以正常訪問

image.png

image.png
3.關(guān)閉一臺(tái)Nginx
我們先把上面剛剛關(guān)閉的一臺(tái)keepalived開啟,然后再試驗(yàn)關(guān)閉Nginx
systemctl start keepalived
開啟后正常情況應(yīng)該是vip重新回到master。
接著關(guān)閉192.168.1.127上面的nginx
systemctl stop nginx
可以看到lvs只有一臺(tái)機(jī)器可以轉(zhuǎn)發(fā)了
ipvsadm

image.png
訪問頁面,也只有一臺(tái)機(jī)器的頁面了

image.png
如果此時(shí)把192.168.1.127上面的nginx開啟,那么又會(huì)自動(dòng)恢復(fù)集群正常的情況了。
作者:linjiajiam
來源:https://www.jianshu.com/p/6b64a78b6424
歡迎關(guān)注“Java引導(dǎo)者”,我們分享最有價(jià)值的Java的干貨文章,助力您成為有思想的Java開發(fā)工程師!
