來(lái)源 | 微觀技術(shù) 作者 | 微觀技術(shù) 大型互聯(lián)網(wǎng)架構(gòu)設(shè)計(jì),講究一個(gè) 如果能掌握這四個(gè)方面,應(yīng)付大廠面試以及日常工作中的架構(gòu)方案設(shè)計(jì),基本不是什么難題。 今天,一起來(lái)學(xué)習(xí)下 一、系統(tǒng)拆分有句古話 "牽一發(fā)而動(dòng)全身"。 面對(duì)一個(gè)龐然大物,如果沒有一個(gè)合理的分工分層。任何一個(gè)小小失誤都會(huì)被無(wú)限放大,釀成巨大災(zāi)難。 萬(wàn)物相通,回到我們的軟件架構(gòu)。 早前的系統(tǒng)都是單體系統(tǒng),比如電商業(yè)務(wù),會(huì)員、商品、訂單、物流、營(yíng)銷等模塊都堆積在一個(gè)系統(tǒng)。每到節(jié)假日搞個(gè)大促活動(dòng),系統(tǒng)擴(kuò)容時(shí),一擴(kuò)全擴(kuò),一掛全掛。只要一個(gè)接口出了問題,整個(gè)系統(tǒng)都不可用。 “雞蛋不能放在一個(gè)籃子里”,這種連帶風(fēng)險(xiǎn)換誰(shuí)都承受不起。 因此, 慢慢的就有了我們現(xiàn)在看到的 二、解耦軟件開發(fā)有個(gè)重要原則“高內(nèi)聚、低耦合”。 小到 就以 Spring 框架給我們提供了一個(gè)很好的思路,里面有個(gè)重要設(shè)計(jì) 核心就是采用動(dòng)態(tài)代理技術(shù),通過(guò)對(duì)字節(jié)碼進(jìn)行增強(qiáng),在方法調(diào)用的時(shí)候進(jìn)行攔截,以便于在方法調(diào)用前后,增加我們需要的額外處理邏輯。 當(dāng)然還有一個(gè)重要思路就是 三、異步同步指一個(gè)進(jìn)程在執(zhí)行請(qǐng)求的時(shí)候,若該請(qǐng)求需要一段時(shí)間才能返回信息,那么這個(gè)進(jìn)程將會(huì)一直等待下去,直到收到返回信息才繼續(xù)執(zhí)行下去。 效率會(huì)大大降低,聰明的人想到了 如果是非實(shí)時(shí)響應(yīng)的動(dòng)作可以采用異步來(lái)完成,線程不需要一直等待,而是繼續(xù)執(zhí)行后面的邏輯。 如:線程池(ThreadPoolExecutor)、消息隊(duì)列等都是這個(gè)原理。 比如一個(gè)用戶在淘寶下了一筆購(gòu)物訂單,關(guān)心的是訂單是否創(chuàng)建成功,能否進(jìn)行后續(xù)的付款流程。 至于其他業(yè)務(wù)動(dòng)作,如短信通知、郵件通知、生成訂單快照、創(chuàng)建超時(shí)任務(wù)記錄,這些非核心動(dòng)作用戶并不是特別關(guān)心。 我們可以采用消息隊(duì)列的 其他事情,由不同的 Task 任務(wù)訂閱消息異步處理,彼此間互不干擾。 四、重試重試主要是體現(xiàn)在遠(yuǎn)程的 RPC 調(diào)用,受 為了提升用戶體驗(yàn),調(diào)用方可以通過(guò) 接口重試是一把雙刃劍,雖然客戶端收到了
關(guān)于
五、補(bǔ)償我們知道不是所有的請(qǐng)求都能收到成功響應(yīng)。除了上面的 業(yè)務(wù)補(bǔ)償根據(jù)處理的方向分為兩部分:
補(bǔ)償有很多的實(shí)現(xiàn)方式: 1、本地建表方式,存儲(chǔ)相關(guān)數(shù)據(jù),然后通過(guò)定時(shí)任務(wù)掃描提取,并借助反射機(jī)制觸發(fā)執(zhí)行。 2、也可以采用簡(jiǎn)單的消息中間件,構(gòu)建業(yè)務(wù)消息體,由下游的消費(fèi)任務(wù)執(zhí)行。如果失敗,可以借助 MQ 的重試機(jī)制,多次重試。 六、備份任何服務(wù)器都有宕機(jī)的可能性,一旦存儲(chǔ)了數(shù)據(jù),帶上狀態(tài),如果發(fā)生故障,數(shù)據(jù)丟失,后果是我們無(wú)法承受的。 所以, 那如何備份,不同的框架有不同的玩法。我們以 Redis 為例: Redis 借助
一旦主節(jié)點(diǎn)掛了怎么辦? 這里引入哨兵機(jī)制。哨兵機(jī)制可以實(shí)現(xiàn)主從庫(kù)的自動(dòng)切換,有效解決了故障轉(zhuǎn)移。整個(gè)過(guò)程分為三個(gè)階段:監(jiān)控、選主、通知。 除了 Redis 中間件外,其他常見的 MySQL、Kafka 消息中間件、HBase 、ES 等 ,凡是涉及到數(shù)據(jù)存儲(chǔ)的介質(zhì),都有備份機(jī)制,一旦主節(jié)點(diǎn)掛了,會(huì)啟用備份節(jié)點(diǎn),保證數(shù)據(jù)不會(huì)丟失。 七、多活策略雖然有了上面的 在一些極端情況,如:機(jī)房斷電、機(jī)房火災(zāi)、地震、山洪等不可抗力因素,所有的服務(wù)器都可能出現(xiàn)故障,無(wú)法對(duì)外提供服務(wù),導(dǎo)致整體業(yè)務(wù)癱瘓。 為了降低風(fēng)險(xiǎn),保證服務(wù)的 24 小時(shí)可用性,我們會(huì)采用 常見的 不同的方案技術(shù)要求、建設(shè)成本、運(yùn)維成本也都不一樣。 多活的技術(shù)方案復(fù)雜,需要考慮的問題點(diǎn)也非常多,這里只是拋磚引玉就不過(guò)多展開。 八、隔離隔離屬于物理層面的分割,將若干的系統(tǒng)低耦合設(shè)計(jì),獨(dú)立部署,從物理上隔開。 每個(gè)子系統(tǒng)有自己獨(dú)立的代碼庫(kù),獨(dú)立開發(fā),獨(dú)立發(fā)布。一旦出現(xiàn)故障,也不會(huì)相互干擾。當(dāng)然如果不同子系統(tǒng)間有相互依賴,這種情況比較特殊,需要有默認(rèn)值或者異常特殊處理,這屬于業(yè)務(wù)層面解決方案。 隔離屬于分布式技術(shù)的衍生產(chǎn)物,我們最常見的微服務(wù)解決方案。 將一個(gè)大型的復(fù)雜系統(tǒng)拆分成若干個(gè)微服務(wù)系統(tǒng),這些微服務(wù)子系統(tǒng)通常由不同的團(tuán)隊(duì)開發(fā)、維護(hù),獨(dú)立部署,服務(wù)之間通過(guò) 隔離使得系統(tǒng)間邊界更加清晰,故障可以更加隔離開來(lái),問題的發(fā)現(xiàn)與解決也更加快速,系統(tǒng)的可用性也更高。 九、限流高并發(fā)系統(tǒng),如果遇到流量洪峰,超過(guò)了當(dāng)前系統(tǒng)的承載能力。我們要怎么辦? 一種方案,照單全收,CPU、內(nèi)存、Load 負(fù)載飆得很高,最后處理不過(guò)來(lái),所有請(qǐng)求都超時(shí)無(wú)法正常響應(yīng)。 另一種解決方案,“舍得,有舍有得”,多余的流量我們直接丟棄。 限流定義:
根據(jù)作用范圍:限流分為單機(jī)版限流、分布式限流。 1、單機(jī)版限流 主要借助于本機(jī)內(nèi)存來(lái)實(shí)現(xiàn)計(jì)數(shù)器,比如通過(guò) AtomicLong#incrementAndGet(),但是要注意之前不用的 key 定期做清理,釋放內(nèi)存。 純內(nèi)存實(shí)現(xiàn),無(wú)需和其他節(jié)點(diǎn)統(tǒng)計(jì)匯總,性能最高。但是優(yōu)點(diǎn)也是缺點(diǎn),無(wú)法做到全局統(tǒng)一化的限流。 2、分布式限流 單機(jī)版限流僅能保護(hù)自身節(jié)點(diǎn),但無(wú)法保護(hù)應(yīng)用依賴的各種服務(wù),并且在進(jìn)行節(jié)點(diǎn)擴(kuò)容、縮容時(shí)也無(wú)法準(zhǔn)確控制整個(gè)服務(wù)的請(qǐng)求限制。而分布式限流,以集群為維度,可以方便地控制這個(gè)集群的請(qǐng)求限制,從而保護(hù)下游依賴的各種服務(wù)資源。 限流支持多個(gè)維度:
常見的限流算法:
十、熔斷熔斷,其實(shí)是對(duì)調(diào)用鏈路中某個(gè)資源出現(xiàn)不穩(wěn)定狀態(tài)時(shí)(如:調(diào)用超時(shí)或異常比例升高),對(duì)這個(gè)資源的調(diào)用進(jìn)行限制,讓請(qǐng)求快速失敗,避免影響到其它的資源而導(dǎo)致級(jí)聯(lián)錯(cuò)誤。 熔斷的主要方式是使用斷路器阻斷對(duì)故障服務(wù)器的調(diào)用。 斷路器有三種狀態(tài),關(guān)閉、打開、半打開。 狀態(tài)機(jī): 1、關(guān)閉(Closed)狀態(tài):在這個(gè)狀態(tài)下,請(qǐng)求都會(huì)被轉(zhuǎn)發(fā)給后端服務(wù)。同時(shí)會(huì)記錄請(qǐng)求失敗的次數(shù),當(dāng)請(qǐng)求失敗次數(shù)在一段時(shí)間超過(guò)一定次數(shù)就會(huì)進(jìn)入打開狀態(tài)。 2、打開(Open)狀態(tài):在這個(gè)狀態(tài)下,熔斷器會(huì)直接拒絕請(qǐng)求,返回錯(cuò)誤,而不去調(diào)用后端服務(wù)。同時(shí),會(huì)有一個(gè)定時(shí)器,時(shí)間到的時(shí)候會(huì)變成半打開狀態(tài)。目的是假設(shè)服務(wù)會(huì)在一段時(shí)間內(nèi)恢復(fù)正常。 3、半打開(Half Open)狀態(tài):在這個(gè)狀態(tài)下,熔斷器會(huì)嘗試把部分請(qǐng)求轉(zhuǎn)發(fā)給后端服務(wù),目的是為了探測(cè)后端服務(wù)是否恢復(fù)。如果請(qǐng)求失敗會(huì)進(jìn)入打開狀態(tài),成功情況下會(huì)進(jìn)入關(guān)閉狀態(tài),同時(shí)重置計(jì)數(shù)。 目前,市面流行的解決方案是阿里的開源框架 十一、降級(jí)降級(jí)是系統(tǒng)保護(hù)的一種重要手段。 正如 “好鋼用在刀刃上”,為了使 比如電商大促,業(yè)務(wù)在峰值時(shí)刻,系統(tǒng)抵擋不住全部的流量時(shí),系統(tǒng)的負(fù)載、CPU 的使用率都超過(guò)了預(yù)警水位,可以對(duì)一些非核心的功能進(jìn)行降級(jí),降低系統(tǒng)壓力,比如把 當(dāng)然,不同業(yè)務(wù)、不同公司,處理方式也各不相同,需要結(jié)合實(shí)際場(chǎng)景,和業(yè)務(wù)方一塊討論,最后達(dá)成一個(gè)統(tǒng)一認(rèn)可的降級(jí)方案。 總結(jié)下來(lái):降級(jí)是通過(guò)暫時(shí)關(guān)閉某些非核心服務(wù)或者組件從而保護(hù)核心系統(tǒng)的可用性。 - END - |
|
來(lái)自: 昵稱10087950 > 《JAVA》