微服務設計—微服務可靠性
在軟體的世界中,故障無處不在。硬碟可能損壞,網路可能中斷,消息可能丟失,內存可能跳變。在一個大規範的分散式軟體系統中,各種各樣的故障層出不窮。很多時候我們期望能夠預防故障的出現,但事實上這幾乎是一個不可能實現的夢想。
因此我們需要轉變思路,從避免故障出現轉向使故障出現時對我們系統不產生影響。現在很多IT公司都參考Netflix的Chaos Monkey對系統進行故障注入測試,比如複位一個VM機,或提升CPU/IO使用率,或是耗盡磁碟空間等故障。這些故障注入甚至會在生產環境中進行,因此所有開發人員很清楚他們開發出的應用必須能夠應對這些故障,而不是祈禱一切正常。
功能降級
在一個Monolithic系統中不需要考慮系統降級的問題,因為系統不是好的就是壞的。但在一個微服務系統中,任何一個系統都可能出錯。比如在某寶的主頁上,同時需要多個服務提供信息,這些服務中的某一個可能出現異常。此時,相對於整個網站不可用,更好的方式是進行服務降級。比如在購物車服務故障的情況下,用戶仍然可以瀏覽商品,只是在將商品添加到購物車時提示客戶「服務暫不可用」。
因此對於開發人員,我們必須清楚的知道,如果我們依賴的一個服務故障了,我們要做什麼處理。
斷路器
當一個微服務使用另一個微服務提供的功能時,需要通過RPC/Message等方式與其通信並通常需要等待其返迴響應。但請求可能因為網路故障導致丟失、或是被請求的服務異常無法響應。為避免因為這些異常導致請求方的資源耗盡,需要引入斷路器。
斷路器向下游系統發送心跳,或是監控對每一個下游系統的請求,一旦察覺這些下游服務出現故障,後續的請求將不會發向此實例,直到下游系統恢復正常。
艙壁
艙壁的概念來源於船舶行業。在船的某個位置破損後,能夠通過隔離此艙壁以保護船的其它部位。
在服務使用多個下游服務的時候,如果一個下游服務出現了故障或是響應緩慢異常,為避免影響對其它下游服務的使用,可以引入艙壁模式。
在使用艙壁時,需要為每一個下游服務建立一個獨立的線程池,這些線程池彼此隔離,因此在一個下游服務出現故障時,並不會影響到對其它下游服務的使用。
冗餘
對於一個高可用的服務,必須具備冗餘能力,當一個實例故障後,可以由其它實例繼續提供服務。這些實例需要被監控,並在實例故障時能夠拉起新的實例。這些服務實例必須具備良好的負載均衡能力,並部署在不同的節點上(最好是不同的物理機,以避免同時故障)。如果實例需要存儲數據,需要通過外置的緩存或DB進行數據的存儲,以保證實例故障時數據不會丟失。
冗災
在現實世界中,我們除了面臨VM或物理機的故障,有時還會有更嚴重的故障,比如整個數據中心可能因為斷電、火災、地震等原因故障。並不是所有的服務都需要在出現這類故障後繼續可用,但我們必須分析清楚在這些場景下,我們需要提供什麼級別的可靠性。
如果服務的數據並不是至關重要,並且在此故障場景下也考慮繼續提供服務,那麼我們可能會考慮只進行最基本的可靠性,比如每天晚上定時備份數據,並在數據中心恢復後再使用備份的數據進行恢復;
如果服務的數據非常重要,則需要保證數據在寫入時就進行跨數據中心的備份;
如果服務必須在此場景下繼續可用,那麼就需要考慮採用跨數據中心的主備、主從甚至是多活;
系列主題
微服務的定義和優缺點
微服務設計模式—API Gateway
微服務設計模式—服務註冊與發現
微服務設計模式—微服務通信
微服務設計—微服務可靠性
微服務設計—微服務部署
微服務設計—將Monolithic重構為微服務
微服務設計—事件驅動架構
推薦閱讀:
※系統設計師必備技能與工具有哪些?
※大型信息系統中的基礎平台有哪些?
※4.1 概要設計
※Raindrop 書籤整理軟體收費版使用感受
※微服務設計—事件驅動架構