
我遇到過不止一次Nginx進程悄悄退出的情況。最難忘的是某天凌晨兩點爆出的那通告警——某業(yè)務(wù)系統(tǒng)前端的Nginx突然完全無響應(yīng)用戶請求全部卡在連接階段等我們摸黑登錄服務(wù)器、檢查日志、重啟服務(wù)、確認恢復(fù)業(yè)務(wù)已經(jīng)斷了將近四十分鐘。那臺Nginx就是典型的單機部署沒有任何冗余俗稱單點。那次事故之后我所在的團隊老老實實地把Nginx高可用集群排上了日程做的就是經(jīng)典的NginxKeepalived主從熱備方案。今天這篇文章我就把從方案選型、環(huán)境規(guī)劃、配置落地到模擬故障切換、處理各種真實坑的完整過程整理出來希望對正在計劃給Nginx加一層保障的運維或后端同學(xué)有實際參考價值。1. 單點事故的代價Nginx高可用到底在解決什么問題1.1 Nginx進程退出之后的連鎖反應(yīng)單點故障這件事聽起來很簡單——一臺機器壞了服務(wù)就斷了。但真正實施下來連鎖反應(yīng)遠比想象中麻煩。那次事故里Nginx不只是負責(zé)轉(zhuǎn)發(fā)請求它前面連著用戶入口后面連著應(yīng)用服務(wù)器。Nginx一掛所有請求進不來后端的應(yīng)用其實還活著但用戶根本夠不著。業(yè)務(wù)側(cè)反饋過來的時候我們連到底是網(wǎng)絡(luò)問題、DNS問題、防火墻問題還是Nginx問題都排查了好一會兒。復(fù)盤時我們發(fā)現(xiàn)單點Nginx的問題不只是進程掛掉這一種可能。機器硬件故障、內(nèi)核崩潰、磁盤寫滿導(dǎo)致的異常、被人誤操作改了配置后reload失敗、機房網(wǎng)絡(luò)閃斷……任何一種情況都能讓Nginx從正常變?yōu)椴豢捎?。有的場景下服?wù)器可能還開著但進程已經(jīng)不在了有的場景下機器徹底失聯(lián)。想要應(yīng)對這一整類問題就必須從架構(gòu)層面做冗余讓故障發(fā)生時業(yè)務(wù)能自動切走而不是等工程師被叫起來手動恢復(fù)。1.2 主從熱備模型虛擬IP與故障漂移主從熱備的基本思路通俗地說就是讓兩臺Nginx節(jié)點組成一個雙人值守的小組。對外只暴露一個虛擬IPVIP平時由主節(jié)點MASTER持有這個VIP并處理全部流量備節(jié)點BACKUP在主節(jié)點正常時處于待命狀態(tài)不接流量只通過心跳監(jiān)控主節(jié)點的健康狀況。一旦主節(jié)點失聯(lián)或Nginx進程異常備節(jié)點會迅速把VIP搶到本機上接管服務(wù)整個過程對調(diào)用方基本不可見。這里最關(guān)鍵的設(shè)計就是虛擬IP??蛻舳嗽L問的始終是這個固定的VIP而不是某一臺具體服務(wù)器的IP。所以無論VIP落在主節(jié)點還是備節(jié)點上對用戶來說入口沒有變。這套思路可以類比小區(qū)配置兩個值班保安住戶進出只認門衛(wèi)室這個位置今天A保安在崗還是B保安在崗住戶不需要關(guān)心只要門衛(wèi)室始終有人就行。兩臺Nginx之間怎么知道對方還活著這就是Keepalived的工作了。Keepalived基于VRRP協(xié)議實現(xiàn)節(jié)點間的狀態(tài)同步和自動failover它會在兩臺設(shè)備之間周期性地發(fā)送心跳報文。心跳連續(xù)丟失達到閾值備節(jié)點就判定主節(jié)點故障立刻在本機綁定VIP、對外發(fā)送免費ARP通告讓交換機把虛擬IP對應(yīng)的流量切換到本機。1.3 為什么鎖定了Keepalived而不是其他高可用方案很多人問過我高可用方案那么多為什么不直接用DNS輪詢、云廠商的負載均衡或者干脆上LVS我的體會是方案沒有絕對的好壞關(guān)鍵是看場景。DNS輪詢的做法是給域名解析多個A記錄指向不同Nginx節(jié)點。好處是配置簡單但壞處也很明顯——DNS解析結(jié)果存在客戶端和Local DNS緩存里某一臺節(jié)點宕機后仍然會有大量請求打到故障IP上。而且這種方案本質(zhì)上是負載均衡不是主備容災(zāi)單個節(jié)點故障時受影響的范圍不好控制。云負載均衡比如各種云SLB在公有云環(huán)境里確實好用托管維護、自帶健康檢查。但如果你所在的環(huán)境是自有機房或者客戶明確要求內(nèi)網(wǎng)閉環(huán)再或者出于成本考慮不想引入額外的LB層Keepalived這種輕量級方案就很有優(yōu)勢。它不需要額外硬件不改變現(xiàn)有Nginx架構(gòu)兩臺服務(wù)器裝上軟件、寫好配置就具備故障漂移能力學(xué)習(xí)和維護成本都不高。2. 環(huán)境規(guī)劃與基礎(chǔ)準備主備節(jié)點、VIP和系統(tǒng)參數(shù)2.1 節(jié)點與IP規(guī)劃動手之前一定要畫一張清晰的規(guī)劃表別等配置寫完了才發(fā)現(xiàn)VIP網(wǎng)段和業(yè)務(wù)網(wǎng)段沖突或者兩臺節(jié)點根本不在同一個二層網(wǎng)絡(luò)里。以我們當(dāng)時的部署為例兩臺Nginx節(jié)點跑在同一個交換機二層網(wǎng)絡(luò)中使用私有地址段。規(guī)劃如下角色主機名物理IP虛擬IP用途MASTERngx-node-01192.168.1.10192.168.1.100接收VIP流量主節(jié)點BACKUPngx-node-02192.168.1.11192.168.1.100主節(jié)點故障時接管VIP虛擬IP必須和兩臺節(jié)點處于同一廣播域內(nèi)Keepalived的VRRP報文依賴組播或多播廣播跨了網(wǎng)段就會失效。生產(chǎn)環(huán)境中建議把Keepalived的心跳通信單獨規(guī)劃一條網(wǎng)線或獨立網(wǎng)段避免業(yè)務(wù)流量高峰期把心跳報文也擠丟了這是后話。操作系統(tǒng)我們用的是CentOS 7.9內(nèi)核版本3.10Keepalived版本1.3.5。當(dāng)然你用其他主流Linux發(fā)行版也完全可以配置思路一致只是包管理命令和部分系統(tǒng)路徑會有差異。2.2 安裝Nginx并準備差異測試頁Nginx的安裝這里不展開細說yum源直接裝即可。裝完之后我給兩臺節(jié)點分別準備了一個不同的首頁文件用于后面的切換測試。主節(jié)點的/usr/share/nginx/html/index.html內(nèi)容h1Node: ngx-node-01/h1 pThis is MASTER nginx instance./p備節(jié)點的/usr/share/nginx/html/index.html內(nèi)容h1Node: ngx-node-02/h1 pThis is BACKUP nginx instance./p同時把Nginx設(shè)為開機自啟systemctl enable nginx systemctl start nginx這樣設(shè)置的目的是為了在驗證故障切換時能通過curl http://192.168.1.100返回的不同頁面內(nèi)容直觀地判斷當(dāng)前VIP到底落在哪臺節(jié)點上。2.3 系統(tǒng)基礎(chǔ)配置防火墻、SELinux和時間同步這塊最容易在部署時被忽略卻在關(guān)鍵時刻拖后腿。首先是防火墻很多人的Keepalived一直報不出心跳排查了一圈發(fā)現(xiàn)是防火墻把VRRP協(xié)議擋了。VRRP使用的不是普通的TCP/UDP端口而是IP協(xié)議號112CentOS中需要放行對應(yīng)的規(guī)則。firewall-cmd --permanent --add-protocolvrrp firewall-cmd --permanent --add-servicehttp firewall-cmd --reload如果是舊版iptables要放行VRRP協(xié)議可以參照iptables -A INPUT -p vrrp -i eth0 -j ACCEPT然后是SELinux。默認的enforcing模式下Keepalived調(diào)用外部腳本、綁定虛擬IP、發(fā)送通告都可能被攔截排查起來非常隱蔽。我們當(dāng)時直接設(shè)置為permissive模式保證功能先跑通生產(chǎn)環(huán)境需要按自己公司的安全基線來權(quán)衡。setenforce 0 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config時間同步也必須做好。Keepalived自身對時間不是特別敏感但整個集群里的日志時間線、證書有效期判斷、業(yè)務(wù)系統(tǒng)時間戳都依賴一致的時間源。用chrony統(tǒng)一對時避免后面排查問題時日志時間對不上。3. Keepalived安裝與核心配置拆解心跳、優(yōu)先級和檢測腳本3.1 VRRP的工作機制與Keepalived的角色切換Keepalived的核心是VRRP虛擬路由冗余協(xié)議。協(xié)議的思想很簡單一組路由器這里就是Nginx節(jié)點共同對外提供一個虛擬IP其中優(yōu)先級最高的節(jié)點成為Master負責(zé)響應(yīng)VIP上的請求Master周期性發(fā)送VRRP廣告報文其余節(jié)點收到后確認Master還活著繼續(xù)待在Backup狀態(tài)。如果Backup在連續(xù)幾個廣告周期內(nèi)都沒收到Master的報文就會認為Master已經(jīng)不可用于是按照優(yōu)先級最高的Backup順序進入Master狀態(tài)接管VIP。Keepalived在這個基礎(chǔ)上又增加了track_script機制——不僅檢測網(wǎng)絡(luò)狀態(tài)還能定期執(zhí)行自定義腳本根據(jù)腳本返回值決定是否降低本節(jié)點優(yōu)先級甚至主動移交VIP。理解這個機制之后再回來看配置就會非常清晰優(yōu)先級、心跳間隔、檢測腳本這三個要素決定了整個集群的切換行為。3.2 主節(jié)點Keepalived配置全解析安裝Keepalivedyum install -y keepalived主節(jié)點的配置文件/etc/keepalived/keepalived.conf如下global_defs { router_id ngx-node-01 enable_script_security } vrrp_script check_nginx { script /usr/local/bin/check_nginx.sh interval 2 timeout 2 weight -20 fall 2 rise 2 } vrrp_instance VI_NGX { state MASTER interface eth0 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 123456 } track_script { check_nginx } virtual_ipaddress { 192.168.1.100/24 dev eth0 } }逐段解釋一下關(guān)鍵配置的含義。global_defs里面的router_id是當(dāng)前節(jié)點的標識在兩臺節(jié)點上必須不同。enable_script_security用于限制Keepalived執(zhí)行外部腳本時的安全性避免腳本環(huán)境變量被濫用官方文檔建議開啟。vrrp_script check_nginx定義了一個檢測任務(wù)。script指定檢測腳本絕對路徑interval 2表示每2秒執(zhí)行一次timeout 2表示腳本執(zhí)行超過2秒視為超時weight -20表示腳本返回非0時當(dāng)前節(jié)點優(yōu)先級降低20fall 2和rise 2表示連續(xù)失敗2次才判定服務(wù)異常連續(xù)成功2次才判定恢復(fù)這是為了防止腳本偶發(fā)抖動導(dǎo)致頻繁切換。vrrp_instance VI_NGX是VRRP實例的配置。state MASTER聲明該節(jié)點初始角色是主節(jié)點interface eth0指定心跳報文走哪塊網(wǎng)卡一定是物理網(wǎng)卡而不是VIP所在的虛擬網(wǎng)卡virtual_router_id 51是一個虛擬路由器ID同一組主備節(jié)點必須保持一致priority 150是節(jié)點優(yōu)先級數(shù)字越大越優(yōu)先成為Masteradvert_int 1是心跳報文發(fā)送間隔單位秒通常保持默認1秒即可。authentication塊配置節(jié)點間認證。auth_type PASS表示密碼認證auth_pass是明文密碼。注意Keepalived只取密碼前8位所以密碼不要超過8個字符否則超出部分會被忽略反而容易造成兩臺節(jié)點配置不一致。virtual_ipaddress配置虛擬IP。192.168.1.100/24 dev eth0表示VIP綁定在eth0上子網(wǎng)掩碼24位。這里有個細節(jié)寫成帶掩碼和dev的形式比只寫一個IP更明確能避免某些系統(tǒng)下路由和ARP異常。3.3 備節(jié)點配置與主節(jié)點的差異備節(jié)點的配置大體復(fù)制主節(jié)點只需要改動四個地方router_id、state、priority和節(jié)點自身標識。備節(jié)點配置如下global_defs { router_id ngx-node-02 enable_script_security } vrrp_script check_nginx { script /usr/local/bin/check_nginx.sh interval 2 timeout 2 weight -20 fall 2 rise 2 } vrrp_instance VI_NGX { state BACKUP interface eth0 virtual_router_id 51 priority 120 advert_int 1 authentication { auth_type PASS auth_pass 123456 } track_script { check_nginx } virtual_ipaddress { 192.168.1.100/24 dev eth0 } }兩個節(jié)點優(yōu)先級相差30這個差值必須大于檢測腳本的weight絕對值。主節(jié)點檢測失敗時優(yōu)先級從150降到130仍然大于備節(jié)點的120主節(jié)點不會因為一次檢測失敗就把VIP讓出去。但如果主節(jié)點整體宕機網(wǎng)絡(luò)斷開、機器失聯(lián)備節(jié)點收不到任何VRRP報文就會直接接管VIP此時優(yōu)先級差就不再重要。理解這個優(yōu)先級與weight之間的數(shù)值關(guān)系才能靈活設(shè)計進程異常時切換、機器宕機時切換、輕微故障時不來回抖的預(yù)期行為。3.4 檢測腳本Nginx是否活著的準確判斷檢測腳本是Keepalived配置中靈魂般的存在它決定了故障到底是整機失聯(lián)還是Nginx進程掛了。我們的腳本如下#!/bin/bash # 檢測 nginx master 進程是否存在 if pidof nginx /dev/null 21; then exit 0 else exit 1 fi腳本邏輯很簡單pidof nginx能查到nginx進程就返回0否則返回1。寫完一定要加上執(zhí)行權(quán)限chmod x /usr/local/bin/check_nginx.sh這個腳本有兩個常見的坑。一個是不要用ps -ef | grep nginx | grep -v grep | wc -l這類方式因為grep自身進程可能匹配到關(guān)鍵字而且統(tǒng)計數(shù)量容易誤判另一個是腳本路徑不要放在/etc/keepalived/目錄下有些Keepalived版本在啟動或重載時會清理該目錄下的非配置文件內(nèi)容腳本容易莫名其妙消失。放在/usr/local/bin這類系統(tǒng)路徑里更安全。也可以做得更嚴格一點比如用Nginx的健康檢查接口配合curl來判斷進程是否真的在服務(wù)請求而不只是進程存在。但對于主從熱備場景進程級檢測通常夠用過度復(fù)雜的健康檢查反而會引入新的誤判因素。4. 主從熱備的驗證實驗?zāi)M宕機、切換和回切全流程4.1 啟動集群并確認VIP歸屬配置全部就緒后在兩臺節(jié)點上啟動Keepalivedsystemctl enable keepalived systemctl start keepalived先看主節(jié)點上VIP是否綁定成功ip addr show eth0正常情況下主節(jié)點的eth0上除了物理IP192.168.1.10還會多出一個192.168.1.100/24的地址。備節(jié)點上不應(yīng)該出現(xiàn)這個VIP。此時訪問VIP應(yīng)該返回主節(jié)點的頁面curl http://192.168.1.100返回內(nèi)容Node: ngx-node-01說明流量確實打在主節(jié)點上。再確認心跳狀態(tài)systemctl status keepalived或者看消息日志tail -f /var/log/messages | grep VRRP能看到類似VRRP_Instance(VI_NGX) Entering MASTER STATE的日志說明節(jié)點正常進入了Master狀態(tài)。4.2 場景一Nginx進程異常觸發(fā)切換生產(chǎn)環(huán)境中進程被誤殺、內(nèi)存不足被OOM殺掉、配置文件錯誤導(dǎo)致worker進程退出這些都是比較常見的故障。我們先用最直接的方式模擬在主節(jié)點上停掉Nginx。systemctl stop nginx然后觀察主節(jié)點的日志會看到檢測腳本連續(xù)執(zhí)行失敗觸發(fā)優(yōu)先級降低最終退出Master狀態(tài)。同時在備節(jié)點上能看到進入Master狀態(tài)的日志。幾條典型的日志片段VRRP_Script(check_nginx) failed VRRP_Instance(VI_NGX) Received lower prio advert, forcing new election VRRP_Instance(VI_NGX) Entering BACKUP STATE備節(jié)點日志VRRP_Instance(VI_NGX) Transition to MASTER STATE VRRP_Instance(VI_NGX) Sending gratuitous ARP on eth0 VRRP_Instance(VI_NGX) Entering MASTER STATE備節(jié)點進入Master后執(zhí)行ip addr show eth0可以看到VIP192.168.1.100已經(jīng)出現(xiàn)在備節(jié)點上而主節(jié)點上的VIP已經(jīng)消失。再次訪問VIPcurl http://192.168.1.100返回內(nèi)容Node: ngx-node-02。整個切換過程從Nginx停止到VIP漂移完成大約3到5秒取決于檢測腳本的間隔和失敗次數(shù)設(shè)置。用戶側(cè)最多只會感覺到一次短暫的連接抖動不會出現(xiàn)長時間無法訪問。4.3 場景二整機宕機與恢復(fù)后的搶占回切更嚴重的故障是主節(jié)點整臺機器宕機比如斷電、硬件故障、系統(tǒng)崩潰。這時主節(jié)點連心跳報文都不再發(fā)送備節(jié)點等待超時后直接接管VIP和上面觀察到的現(xiàn)象基本一致。區(qū)別在于整機宕機時備節(jié)點完全收不到Master的VRRP報文所以它在advert_int乘以幾倍的超時窗口之后就會切換通常也是一到三秒級別。接下來看回切行為。把主節(jié)點的Nginx和Keepalived都恢復(fù)起來systemctl start nginx systemctl start keepalived在默認配置下主節(jié)點啟動后會重新以150的優(yōu)先級參與選舉備節(jié)點收到更高優(yōu)先級的報文后自動退出Master狀態(tài)VIP會回切到主節(jié)點。這個行為叫搶占preempt。從高可用角度來說搶占能保證流量回到配置更完善、資源更充裕的主節(jié)點上但也會帶來一個問題如果主節(jié)點反復(fù)抖動每次回切都會造成一次連接中斷。如果業(yè)務(wù)不希望主節(jié)點恢復(fù)后立刻搶回VIP可以在備節(jié)點配置中加入nopreempt讓角色切換只在故障發(fā)生時觸發(fā)正常情況下VIP穩(wěn)定在當(dāng)前節(jié)點。但要注意nopreempt的使用有講究需要在vrrp_instance中配置并且主節(jié)點通常也要把state設(shè)為BACKUP單純通過優(yōu)先級區(qū)分誰是事實主節(jié)點否則搶占行為不會被完全抑制。4.4 切換過程中的連接保持問題主從熱備能解決服務(wù)入口不中斷但它解決不了正在進行的請求不中斷。舉個例子用戶正在通過VIP下載一個大文件或者長輪詢接口正在等待數(shù)據(jù)。切換發(fā)生時TCP連接的狀態(tài)存儲在主節(jié)點的內(nèi)核協(xié)議棧上而備節(jié)點上并沒有這些連接狀態(tài)所以VIP漂移后這些存量連接會全部斷開用戶需要重新發(fā)起請求。對于大多數(shù)HTTP短連接業(yè)務(wù)來說影響的只是切換瞬間的少量請求重試一次就夠了。如果業(yè)務(wù)對中斷容忍度極低單純NginxKeepalived是不夠的還需要在更上層配合會話保持策略、客戶端重試機制或者引入四層負載均衡方案把連接層的狀態(tài)管理從Nginx節(jié)點中抽離出來。搞清楚主從熱備的邊界比盲目追求零切換更實際。5. 實際部署中容易踩的坑與調(diào)優(yōu)建議5.1 那些隱蔽的坑防火墻、SELinux、腳本權(quán)限和腦裂每次幫別人排查Keepalived問題最后發(fā)現(xiàn)的大多不是配置理解問題而是這些不起眼的環(huán)境問題。防火墻不放行VRRP是最常見的一個。現(xiàn)象是兩臺節(jié)點都認為自己是Master或者備節(jié)點一直收不到心跳日志里沒有任何切換動作。檢查方法很簡單在兩臺節(jié)點上tcpdump -i eth0 vrrp看能否抓到對方的VRRP報文。抓不到基本就是被防火墻或交換機策略擋住了。SELinux影響的是腳本執(zhí)行。我遇到過檢測腳本明明有執(zhí)行權(quán)限手動跑也沒問題但Keepalived執(zhí)行時就是失敗的情況日志里只顯示腳本超時或返回異常。后來發(fā)現(xiàn)是SELinux攔截了對腳本文件的訪問。要么把腳本所在目錄的權(quán)限調(diào)整好要么直接臨時改成permissive模式驗證。腳本權(quán)限更基礎(chǔ)卻最容易犯。chmod x少了配置寫錯了路徑腳本用了#!/bin/bash但文件格式是CRLF這些都會導(dǎo)致檢測腳本不可用。建議寫完腳本先手動跑一次確認返回碼符合預(yù)期再交給Keepalived去調(diào)用。腦裂是雙節(jié)點集群最怕的問題即兩個節(jié)點都認為自己是MasterVIP同時出現(xiàn)在兩臺機器上。這種情況會導(dǎo)致流量在不同節(jié)點之間來回抖動甚至出現(xiàn)數(shù)據(jù)不一致。觸發(fā)原因通常是心跳網(wǎng)絡(luò)中斷而業(yè)務(wù)網(wǎng)絡(luò)正?;蛘叻阑饓Π腴_只放行了部分方向。緩解措施包括心跳線用獨立網(wǎng)段或直連網(wǎng)線檢測腳本里加上對端IP連通性檢查以及利用告警機制及時察覺雙Master狀態(tài)。5.2 調(diào)優(yōu)參數(shù)與狀態(tài)通知讓集群可控可觀測Keepalived配置文件里值得優(yōu)化的參數(shù)不少我挑幾個重點說說。advert_int決定心跳頻率。默認1秒適合大多數(shù)場景調(diào)小到0.5秒能加快故障感知但會增加網(wǎng)絡(luò)壓力和誤判概率調(diào)大到2秒以上則切換變慢適合心跳網(wǎng)絡(luò)帶寬受限的場景。這個值需要和檢測腳本的interval配合考慮不要為了追求極端速度犧牲穩(wěn)定性。weight的取值直接影響切換行為。如果你希望只有進程死掉才切換weight的絕對值必須小于主備優(yōu)先級差值如果你希望檢測失敗就立即切換weight可以把主節(jié)點優(yōu)先級壓到備節(jié)點之下。我們配置里主備優(yōu)先級相差30、weight是20就意味著進程異常時主節(jié)點還在只是優(yōu)先級降到130繼續(xù)留著。但如果加上fall 2的連續(xù)失敗判定實際效果比單純看weight更可靠因為它是基于連續(xù)失敗次數(shù)的綜合判斷。狀態(tài)通知是個容易被忽略但非常實用的功能??梢栽趘rrp_instance中配合notify_master、notify_backup、notify_fault在角色切換時觸發(fā)自定義腳本發(fā)送釘釘、企業(yè)微信或郵件告警。實現(xiàn)故障發(fā)生時第一時間知道而不是等業(yè)務(wù)側(cè)反饋才知道。一個簡單的通知腳本示例如下#!/bin/bash # /usr/local/bin/notify_keepalived.sh case $1 in master) echo $(date) become MASTER /var/log/keepalived-notify.log # 在這里調(diào)用 curl 發(fā)送 webhook 告警 ;; backup) echo $(date) become BACKUP /var/log/keepalived-notify.log ;; fault) echo $(date) enter FAULT /var/log/keepalived-notify.log ;; esac配置中對應(yīng)加入notify_master /usr/local/bin/notify_keepalived.sh master notify_backup /usr/local/bin/notify_keepalived.sh backup notify_fault /usr/local/bin/notify_keepalived.sh fault有了通知主從切換不再是一個黑盒事件每次切換都有跡可循。5.3 從主從到更復(fù)雜的形態(tài)雙活與熱備的擴展主從熱備是一個很好的起點但不是終點。當(dāng)兩臺Nginx機器跑在主從模式下時備機大部分時間都是空閑的從資源利用率角度看有點浪費。如果業(yè)務(wù)量增長可以考慮把架構(gòu)演進為互為主備的雙活模式兩臺節(jié)點各自帶一個VIP分別承接一部分業(yè)務(wù)流量同時互為對方的備份。Keepalived配置里增加第二個vrrp_instance讓A節(jié)點在實例1中是MASTER、在實例2中是BACKUPB節(jié)點則反著來這樣兩臺機器的資源都利用起來了。還可以在Nginx前面加LVS或四層負載均衡形成兩級的高可用體系?;蛘甙袺eepalived的檢測腳本擴展成更完整的健康檢查比如檢查后端應(yīng)用端口、檢查磁盤空間、檢查系統(tǒng)負載讓集群的故障切換決策更聰明。但這些都屬于有了主從熱備之后的下一步延伸先把基礎(chǔ)的主從熱備穩(wěn)定跑通再根據(jù)業(yè)務(wù)需要逐層加碼才是穩(wěn)妥的演進路徑。最后分享一個我個人的習(xí)慣每半年至少手動做一次主從切換演練把切換腳本、通知腳本、備節(jié)點上的配置一致性全部驗證一遍。人類是健忘的動物集群也一樣——太久不切換真的到了需要切換的那天往往會發(fā)現(xiàn)備節(jié)點配置文件早就過期了或者腳本權(quán)限被人動過或者防火墻策略早就變了。演練不一定能完全避免事故但至少能保證在事故來臨時你不需要一邊盯著日志一邊祈禱。