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