高可用性(HA),顧名思義,就是盡可能地減少系統(tǒng)不能提供服務(wù)的時(shí)間;如果一個(gè)系統(tǒng)能夠一直保持工作狀態(tài),可以對外提供服務(wù),那么我們就說系統(tǒng)的可用性是100%;大部分公司不會(huì)把話說這么滿,所以經(jīng)常會(huì)提出三個(gè)9、四個(gè)9的目標(biāo),也就是全年系統(tǒng)可用性為99.9%、99.99%。
那么如何保證系統(tǒng)的高可用呢?我認(rèn)為核心的思想就是【
可以看到,架構(gòu)的每一個(gè)部分都是單點(diǎn)的話,簡直是風(fēng)險(xiǎn)重重,任何一個(gè)環(huán)節(jié)出現(xiàn)了問題,可能會(huì)造成整個(gè)系統(tǒng)垮掉(緩存部分可能不會(huì)直接影響系統(tǒng),但往往緩存失去效果之后,會(huì)拖垮數(shù)據(jù)庫),解決方法也很容易,其實(shí)就是把系統(tǒng)的每個(gè)部分都增加冗余:
客戶端到Web應(yīng)用:要增加Web應(yīng)用,首先要增加反向代理層,也就是負(fù)載均衡,比如Nginx;不過如果只部署一個(gè)Nginx的話,它又是一個(gè)單點(diǎn)了,通常我們會(huì)部署多臺(tái),一臺(tái)提供服務(wù),另外的相當(dāng)于“備胎”,通過keepalived的方式監(jiān)控工作中的Nginx是否存活,當(dāng)主服務(wù)器發(fā)生故障無法對外提供服務(wù)時(shí),動(dòng)態(tài)將virtualIP(虛IP)切換到備用機(jī),繼續(xù)提供服務(wù)。 負(fù)載均衡到Web應(yīng)用:搭建多個(gè)Web應(yīng)用,在負(fù)載均衡如Nginx中配置多個(gè)Web端的地址,并且可以監(jiān)控多個(gè)Web端的存活性,當(dāng)監(jiān)控到某臺(tái)應(yīng)用掛掉,那么Nginx不在將請求分發(fā)到這臺(tái)機(jī)器上。 Web應(yīng)用到服務(wù)層:這里有很多種實(shí)現(xiàn)方式,比如服務(wù)層前端也掛負(fù)載均衡,或者走客戶端內(nèi)的負(fù)載均衡(這里Web應(yīng)用就是客戶端,相當(dāng)于配置多個(gè)服務(wù)層的地址,每次請求按照一定規(guī)則,選取連接來訪問下游服務(wù),并使用service-connection-pool監(jiān)控服務(wù)層應(yīng)用的存活性);也可以使用服務(wù)注冊發(fā)現(xiàn)的方式(可提供服務(wù)的應(yīng)用才會(huì)出現(xiàn)在注冊中心)。 服務(wù)層到緩存:緩存的存在,本身就是一種冗余;緩存層也可以通過集群來解決緩存層的高可用問題。以Redis為例,支持主從同步,而且有sentinel哨兵機(jī)制,來做Redis的存活性檢測。 服務(wù)層到數(shù)據(jù)庫:數(shù)據(jù)庫一般會(huì)采用主從架構(gòu);數(shù)據(jù)庫【讀】的高可用,通常使用db-connection-pool來保證自動(dòng)故障轉(zhuǎn)移;而【寫】操作,通常需要keepalived+virtualIP(虛IP)自動(dòng)切換。
以上都是保證系統(tǒng)高可用的方案,盡量做到客戶端所有的請求都可以響應(yīng),但是系統(tǒng)資源不可能無限投入,所以需要一些方案保證系統(tǒng)的高可用,不過需要【犧牲】部分用戶:
限流:我們接口只能支持200的并發(fā),我們的頁面只能支持一萬人同時(shí)訪問,那么多余的部分,對不起,我需要限制你們進(jìn)入;常見的限流算法有:漏桶、令牌桶;
降級(jí):犧牲非核心的業(yè)務(wù)功能,保證核心功能的穩(wěn)定運(yùn)行;
熔斷:當(dāng)服務(wù)鏈路中(A調(diào)B,B調(diào)C,C調(diào)D),某個(gè)服務(wù)響應(yīng)時(shí)間過長或失敗,會(huì)進(jìn)行服務(wù)的降級(jí),進(jìn)而熔斷該節(jié)點(diǎn)服務(wù)的調(diào)用,快速返回錯(cuò)誤信息;不過嘛,我從來沒有見過誰敢用熔斷...
灰度發(fā)布:將部分流量導(dǎo)到新上線的應(yīng)用上,來驗(yàn)證新的功能修改,如果上線后有BUG,也可以快速回滾,盡可能降低發(fā)布的風(fēng)險(xiǎn)。