我們知道 Nginx反向代理可以簡單的實現負載均衡(不知道的話可以先去百度瞭解下,這裏就當你知道了,haha...)
如果服務器節點(Service節點)掛了,可以使用其他組件去做心跳檢測(Consul、k8s等等),今天先不說這些。
今天主要說說:如果Nginx代理所在服務器掛了該怎麼辦?如何實現Nginx的高可用?
先看下圖:
解釋:
1,兩臺Nginx服務器,一主一備,也可以一主N備,每臺Nginx服務器上負載有兩臺Service節點
2,客戶端發起一個請求 ,請求沒有到Nginx的實際IP上,而是請求的虛擬IP(會和實際IP通過配置文件進行綁定)
3,這時候如果有一臺Nginx服務器掛了,Keepalived會自動在備Nginx服務器上選一臺當主服務器
接下來落地實操
1,準備2臺服務器(Linux),這裏示例IP分別爲:192.168.1.104、192.168.1.105
2,設置發送郵件的功能,後邊使用:參考另一篇博文: Linux系統下用mail(mailx)發送郵件
3,兩臺服務器上分別安裝 Docker (參考另一篇博文:https://www.cnblogs.com/peterzhang123/p/13858345.html)
4,在兩臺機器的Docker上分別安裝Nginx,對外訪問端口爲:4001 (參考另一篇博文:https://www.cnblogs.com/peterzhang123/p/13864381.html)
5,在兩臺機器上分別安裝 keepalived (注意:keepalived安裝在實體機上,不是安裝到Docker上)
6,準備一個虛擬IP,說人話就是弄個假IP,當前網段內沒人用該IP 例如:192.168.1.110
7,準備兩個Service服務(ApI應用),爲了演示,這裏提供兩個不同端口IP地址作爲負載(192.168.1.102:5001,192.168.1.102:5002)
1,配置Nginx內容
upstream group1 { server 192.168.1.102:5001; server 192.168.1.102:5002; } server { listen 80; server_name localhost; location / { proxy_pass http://group1/; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
2,在Linux主機上安裝 Keepalived
#切換到 /usr目錄下 cd /usr #安裝keepalived環境依賴 yum install -y gcc openssl-devel popt-deve #安裝keepalived yum install keepalived -y
#驗證是否安裝成功
rpm -q -a keepalived
#移除
yum remove keepalived
安裝之後,在 /etc/keepalived目錄下有個 keepalived.conf 配置文件
修改 keepalived.conf 配置文件,配置內容參考如下 (注意區分 主/備的配置不一樣)
! Configuration File for keepalived global_defs { # 通知郵件服務器的配置 # 當master失去VIP或則VIP的時候,會發一封通知郵件到your-[email protected] notification_email { 131xxxxx@qq.com # 收件人 } notification_email_from [email protected] # 郵件發送方地址 smtp_server smtp.163.com # 163郵件服務器 smtp_connect_timeout 30 # 郵件服務器超時時間 router_id LVS_DEVEL # 唯一ID,設置成IP也行 vrrp_mcast_group4 192.168.1.104 # 當前服務器的IP } # 檢查nginx狀態的腳本,健康監測腳本 vrrp_script chk_http_port { script "/etc/keepalived/nginx_check.sh" # 腳本路徑 interval 2 # 腳本執行間隔時間 weight 3 } vrrp_instance VI_1 { state MASTER # 主機使用: MASTER 備機使用: BACKUP interface ens33 # 實例綁定的網卡, 用ip a命令查看網卡編號 virtual_router_id 51 # 虛擬路由標識,主、備服務器ID必須一樣 priority 100 # 優先級,備份服務上將100改爲小於100,可配置成90 advert_int 1 # 主備之間同步檢查的時間間隔單位秒 authentication { # 驗證類型和密碼 auth_type PASS # 驗證類型有兩種 PASS和HA auth_pass 1111 # 驗證密碼,在一個實例中主備密碼保持一樣 } virtual_ipaddress { # 虛擬IP地址,可以有多個,每行一個,不需要指定端口,端口使用的是Nginx容器的端口(Port:4001) 192.168.1.110 } track_script { # 調用上邊的腳本 chk_http_port }
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
健康監測腳本內容,如下:
#!/bin/bash #version 0.0.1 A=`ps -C nginx --no-header |wc -l` if [ $A -eq 0 ];then systemctl restart docker #判斷docker是否能啓動 sleep 2 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then systemctl stop keepalived fi fi
腳本說明:
當nginx進程不存在時,會自動重啓docker服務;
docker服務啓動時會自動啓動nginx容器;再次檢查nginx進程,如果不存在,就停止keepalived服務,然後NGINX_BACKUP主機會自動接替NGINX_MASTER的工作;
將健康監測腳本文件:nginx_check.sh 放到配置文件中的路徑下
有2個地方需要注意:
a,將Docker中的Nginx容器設置成開機自動啓動,在每臺nginx服務器上執行如下命令
docker update --restart=always nginx
b,給 keepalived 監控腳本添加執行權限,在每臺機器上執行如下命令
chmod +x /etc/keepalived/nginx_check.sh
3,notify.sh 通知腳本
#!/bin/bash # contact='[email protected]' notify() { mailsubject="$(hostname) to be $1, vip floating" mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" echo "$mailbody" | mailx -v -s "$mailsubject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 1 ;; esac
通知文件:notify.sh 同樣放到路徑 /etc/keepalived 下。
4,啓動 keepalived 服務,兩臺都要啓動
systemctl enable keepalived #將 keepalived 設置開機啓動
systemctl start keepalived #啓動服務
systemctl status keepalived #查看服務狀態
systemctl restart keepalived #重啓服務
systemctl stop keepalived #停止服務
4,最後測試,使用虛擬Ip測試,(截圖僅作參考 )
第一次訪問:http://192.168.2.110:4001/weatherforecast
刷新地址之後,返回另一個Service服務節點
這時候把主Nginx代理所在的服務停掉,繼續訪問以上地址,發現還是可以正常訪問!
在主Nginx所在服務器使用命令 ip a 也能查看到 你設置的虛擬IP已經綁定到網卡上(查看備Nginx服務上是未綁定的)
最後測試收到的郵件
遺留問題:
1,當Master的Nginx訪問某個服務時,在請求還未返回時就宕機了,這時候備Nginx會接着上一個請求繼續訪問嗎?有待驗證!下次分解!