可容錯的微服務架構設計

2020-10-14 啟迪雲Tuscloud

微服務架構可以通過明確定義的服務邊界來隔離故障。但是像在每個分布式系統中一樣,發生網絡、硬體、應用級別的錯誤都是很常見的。由於服務依賴關係,任何組件可能暫時無法提供服務。為了儘量減少部分中斷的影響,我們需要構建容錯服務,來優雅地處理這些中斷的響應結果。

本文介紹了基於RisingStack 的 Node.js 諮詢和開發經驗構建和操作高可用性微服務系統的最常見技術和架構模式。

如果你不熟悉本文中的模式,那並不一定意味著你做錯了。建立可靠的系統總是會帶來額外的成本。


微服務架構的風險

微服務架構將應用程式邏輯移動到服務,並使用網絡層在它們之間進行通信。這種通過網絡間通信代替單應用程式內調用的做法,會帶來額外的延遲,以及需要協調多個物理和邏輯組件的系統複雜度。分布式系統的複雜性增加也將導致更高的網絡故障率。

微服務體系結構的最大優勢之一是,團隊可以獨立設計,開發和部署他們的服務。他們對服務的生命周期擁有完全的所有權。這也意味著團隊無法控制他們依賴的服務,因為它更有可能由不同的團隊管理。使用微服務架構,我們需要記住,提供者服務可能會臨時不可用,由於其他人員發行的錯誤版本,配置以及其他更改等。


優雅的服務降級

微服務架構的最大優點之一是您可以隔離故障,並在當組件單獨故障時,進行優雅的服務降級。例如,在中斷期間,照片共享應用程式中的客戶可能無法上傳新圖片,但仍可以瀏覽,編輯和共享其現有照片。

微服務容錯隔離

在大多數情況下,由於分布式系統中的應用程式相互依賴,因此很難實現這種優雅的服務降級,您需要應用幾種故障轉移的邏輯(其中一些將在本文後面介紹),以為暫時的故障和中斷做準備。

服務間彼此依賴,再沒有故障轉移邏輯下,服務全部失敗。


變更管理

Google的網站可靠性小組發現,大約70%的中斷是由現有系統的變化引起的。當您更改服務中的某些內容時,您將部署新版本的代碼或更改某些配置 - 這總有可能會造成故障,或者引入新的bug。

在微服務架構中,服務依賴於彼此。這就是為什麼你應該儘量減少故障並限制它的負面影響。要處理變更中的問題,您可以實施變更管理策略和自動回滾機制。

例如,當您部署新代碼或更改某些配置時,您應該先小範圍的進行部分的替換,以漸進式的方式替換服務的全部實例。在這期間,需要監視它們,如果您發現它們對您的關鍵指標有負面影響,應立即進行服務回滾,這稱為「金絲雀部署」。


變更管理 - 回滾部署

另一個解決方案可能是您運行兩個生產環境。您始終只能部署其中一個,並且在驗證新版本是否符合預期之後才,將負載均衡器指向新的。這稱為藍綠或紅黑部署。

回滾代碼不是壞事。你不應該在生產中遺留錯誤的代碼,然後考慮出了什麼問題。如果必要,越早回滾你的代碼越好。


健康檢查與負載均衡

實例由於出現故障、部署或自動縮放的情況,會進行持續啟動、重新啟動或停止操作。它可能導致它們暫時或永久不可用。為避免問題,您的負載均衡器應該從路由中跳過不健康的實例,因為它們當前無法為客戶或子系統提供服務。

應用實例健康狀況可以通過外部觀察來確定。您可以通過重複調用GET /health端點或通過自我報告來實現。現在主流的服務發現解決方案,會持續從實例中收集健康信息,並配置負載均衡器,將流量僅路由到健康的組件上。


自我修復

自我修復可以幫助應用程式從錯誤中恢復過來。當應用程式可以採取必要步驟從故障狀態恢復時,我們就可以說它是可以實現自我修復的。在大多數情況下,它由外部系統實現,該系統會監視實例運行狀況,並在較長時間內處於故障狀態時重新啟動它們。自我修復在大多數情況下是非常有用的。但是在某些情況下,持續地重啟應用程式可能會導致麻煩。當您的應用程式由於超負荷或其資料庫連接超時而無法給出健康的運行狀況時,這種情況下的頻繁的重啟就可能就不太合適了。

對於這種特殊的場景(如丟失的資料庫連接),要實現滿足它的高級自我修復的解決方案可能很棘手。在這種情況下,您需要為應用程式添加額外的邏輯來處理邊緣情況,並讓外部系統知道實例不需要立即重新啟動。


故障轉移緩存

由於網絡問題和我們系統的變化,服務經常會失敗。然而,由於自我修復和負載均衡的保障,它們中的大多數中斷是臨時的,我們應該找到一個解決方案,使我們的服務在這些故障時服務仍就可以工作。這就是故障轉移緩存的作用,它可以幫助並為我們的應用程式在服務故障時提供必要的數據。

故障轉移緩存通常使用兩個不同的到期日期; 較短的時間告訴您在正常情況下緩存可以使用的過期時間,而較長的時間可以在服務故障時緩存依舊可用的過期時間。

故障轉移緩存

請務必提及,只有當服務使用過時的數據比沒有數據更好時,才能使用故障轉移緩存。

要設置緩存和故障轉移緩存,可以在 HTTP 中使用標準響應頭。

例如,使用 max-age 屬性可以指定資源被視為有效的最大時間。使用 stale-if-error 屬性,您可以明確在出現故障的情況下,依舊可以從緩存中獲取資源的最大時間。

現代的 CDN 和負載均衡器都提供各種緩存和故障轉移行為,但您也可以為擁有標準可靠性解決方案的公司創建一個共享庫。


重試邏輯

在某些情況下,我們無法緩存數據,或者我們想對其進行更改,但是我們的操作最終都失敗了。對於此,我們可以重試我們的操作,因為我們可以預期資源將在一段時間後恢復,或者我們的負載均衡器將請求發送到了健康的實例上。

您應該小心地為您的應用程式和客戶端添加重試邏輯,因為大量的重試可能會使事情更糟,甚至阻止應用程式恢復,如當服務超載時,大量的重試只能使狀況更糟。

在分布式系統中,微服務系統重試可以觸發多個其他請求或重試,並啟動級聯效應。為了最小化重試的影響,您應該限制它們的數量,並使用指數退避算法來持續增加重試之間的延遲,直到達到最大限制。

當客戶端(瀏覽器,其他微服務等)發起重試,並且客戶端不知道在處理請求之前或之後操作失敗時,您應該為你的應用程式做好冪等處理的準備。例如,當您重試購買操作時,您不應該再次向客戶收取費用。為每個交易使用唯一的冪等值鍵可以幫助處理重試。


限流器和負載降級

流量限制是在一段時間內定義特定客戶或應用程式可以接收或處理多少個請求的技術。例如,通過流量限制,您可以過濾掉造成流量峰值的客戶和服務,或者您可以確保您的應用程式在自動縮放無法滿足時,依然不會超載。

您還可以阻止較低優先級的流量,為關鍵事務提供足夠的資源。

限流器可以阻止流量峰值產生

有一個不同類型的限流器,叫做並發請求限制器。當您有重要的端點,您不應該被調用超過指定的次數,而您仍然想要能提供服務時,這將是有用的。

負載降級的一系列使用,可以確保總是有足夠的資源來提供關鍵交易。它為高優先級請求保留一些資源,不允許低優先級的事務使用它們。負載降級開關是根據系統的整體狀態做出決定,而不是基於單個用戶的請求量大小。負載降級有助於您的系統恢復,因為當你有一個偶發事件時(可能是一個熱點事件),您仍能保持核心功能的正常工作。

要了解有關限流器和負載降級的更多信息,我建議查看這篇Stripe的文章。


快速失敗原則與獨立性

在微服務架構中,我們想要做到讓我們的服務具備快速失敗與相互獨立的能力。為了在服務級別上進行故障隔離,我們可以使用艙壁模式。你可以在本文的後面閱讀更多有關艙壁的內容。

我們也希望我們的組件能夠快速失敗,因為我們不希望對於有故障的服務,在請求超時後才斷開。沒有什麼比掛起的請求和無響應的 UI 更令人失望。這不僅浪費資源,而且還會影響用戶體驗。我們的服務在調用鏈中是相互調用的,所以在這些延遲累加之前,我們應該特別注意防止掛起操作。

你想到的第一個想法是對每個服務調用都設置明確的超時等級。這種方法的問題是,您不能知道真正合理的超時值是多少,因為網絡故障和其他問題發生的某些情況只會影響一兩次操作。在這種情況下,如果只有其中一些超時,您可能不想拒絕這些請求。

我們可以說,在微服務種通過使用超時來達到快速失敗的效果是一種反模式的,你應該避免使用它。取而代之,您可以應用斷路器模式,依據操作的成功與失敗統計數據決定。


艙壁模式

工業中使用艙壁將船舶劃分為幾個部分,以便在船體破壞的情況下,可以將船舶各個部件密封起來。

艙壁的概念在軟體開發中可以被應用在隔離資源上。

通過應用艙壁模式,我們可以保護有限的資源不被耗盡。例如,對於一個有連接數限制的資料庫實例來說,如果我們有兩種連接它的操作,我們採用可以採用兩個連接池的方式進行連接,來代替僅採用一個共享連接池的方式。由於這種客戶端與資源進行了隔離,超時或過度使用池的操作頁不會使其他操作失敗。

鐵達尼號沉沒的主要原因之一是其艙壁設計失敗,水可以通過上面的甲板倒在艙壁的頂部,導致整個船體淹沒。

鐵達尼號艙壁設計(無效的設計)


斷路器

為了限制操作的持續時間,我們可以使用超時。超時可以防止掛起操作並保持系統響應。然而,在微服務中使用靜態、精細的超時是一種反模式,因為我們處於高度動態的環境中,幾乎不可能提出在每種情況下都能正常工作的正確的時間限制。

替代這種靜態超時的手段是,我們可以使用斷路器來處理錯誤。斷路器以現實世界的電子元件命名,因為它們的作用是相同的。您可以保護資源,並幫助他們使用斷路器進行恢復。它們在分布式系統中非常有用,因為在分布式系統中,重複故障可能導致雪球效應並使整個系統癱瘓。

當特定類型的錯誤在短時間內多次發生時,斷路器會被斷開。開路的斷路器可以防止進一步的請求 - 就像我們平時所說的電路跳閘一樣。斷路器通常在一定時間後關閉,在這期間可以為底層服務提供足夠的空間來恢復。

請記住,並不是所有的錯誤都應該觸發斷路器。例如,您可能希望跳過客戶端問題,例如具有4xx響應代碼的請求,但不包括5xx伺服器端故障。一些斷路器也具有半開狀態。在這種狀態下,服務發送第一個請求以檢查系統可用性,同時讓其他請求失敗。如果這個第一個請求成功,它將使斷路器恢復到關閉狀態並使流量流動。否則,它保持打開。

斷路器


測試故障

您應該不斷測試您系統的常見問題,以確保您的服務可以抵抗各種故障。您應經常測試故障,讓您的團隊具備故障處理的能力。

對於測試,您可以使用外部服務來標識實例組,並隨機終止此組中的一個實例。這樣,您可以準備單個實例故障,但您甚至可以關閉整個區域來模擬雲提供商的故障。

最流行的測試解決方案之一是 Netflix 的 ChaosMonkey 彈性工具。


結尾

實施和運行可靠的服務並不容易。您需要付出很多努力,同時公司也要有相應的財力投入。

可靠性有很多層次和方面,因此找到最適合您團隊的解決方案很重要。您應該使可靠性成為您的業務決策流程中的一個因素,並為其分配足夠的預算和時間。


主要收穫

  • 動態環境和分布式系統(如微服務)會導致更高的故障機率;
  • 服務應該做到故障隔離,到達優雅降級,來提升用戶體驗;
  • 70%的中斷是由變化引起的,代碼回滾不是一件壞事;
  • 做到服務快速失敗與獨立性。團隊是無法控制他們所依賴的服務情況;
  • 緩存、艙壁、斷路器和限流器等架構模式與技術有助於構建可靠的微服務架構。

譯者:起個帥的名

來源:https://github.com/jasonGeng88/blog

原文地址

https://blog.risingstack.com/designing-microservices-architecture-for-failure/

相關焦點

  • 阿里微服務布道師:詳解微服務架構設計
    (設計系統的組織,其產生的設計和架構等價於組織間的溝通結構。)微服務也指一種種鬆耦合的、有一定的有界上下文的面向服務架構。也就是說,如果每個服務都要同時修改,那麼它們就不是微服務,因為它們緊耦合在一起;如果你需要掌握一個服務太多的上下文場景使用條件,那麼它就是一個有上下文邊界的服務,這個定義來自DDD領域驅動設計。
  • 分布式微服務架構設計原理
    總線根據路程的編排將服務的輸出轉化為流程的下一個輸出節點缺點:1、ESB服務過重的整體服務2、通過ESB試圖隱藏系統內部的複雜性,但是系統內部複雜性依舊存在三、微服務架構2、去中心化服務治理微服務架構倡導去中心化的服務管理和治理
  • 微服務架構的分布式容錯 · SOSP 2019
    圖 1 - C/S 模型與微服務架構微服務架構的複雜性來源於服務之間的大量交互以及網絡請求的不確定性現實世界中微服務之間的交互遠遠比上圖展示的複雜得多,但是這個簡單的模型已經可以足夠說明微服務架構中服務交互對保證正確性帶來的影響了。
  • Github標星67.9k的微服務架構以及架構設計模式筆記我粉了
    最後,一般提到微服務都離不開DevOps和Docker,理解微服務架構是核心,devops和docker是工具,是手段。下面就一起通過兩份文檔來深入了解微服務架構與它的設計模式,如果各位大佬對微服務架構有什麼獨特的見解歡迎在評論區留言指正。
  • 阿里架構師,講述基於微服務的軟體架構模式(附資料)微服務
    (設計系統的組織,其產生的設計和架構等價於組織間的溝通結構。)微服務也指一種種鬆耦合的、有一定的有界上下文的面向服務架構。也就是說,如果每個服務都要同時修改,那麼它們就不是微服務,因為它們緊耦合在一起;如果你需要掌握一個服務太多的上下文場景使用條件,那麼它就是一個有上下文邊界的服務,這個定義來自DDD領域驅動設計。
  • 微服務架構:初識Spring Cloud
    現在無論大小公司,都會講究微服務設計,無論應用大小,都會進行微服務架構,面試的時候,也會把微服務當成必談的知識點。那麼什麼是微服務呢?,簡單的來說,微服務是系統架構上的一種設計風格,它的目的就是將一個原本獨立垂直的系統拆分成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間是通過基於HTTP的Restful API進行通信協議。
  • 詳解微服務架構(一):什麼是微服務
    這一切都催生了新的架構設計風格 – 微服務架構的出現。什麼是微服務微服務是一種架構風格,一個大型複雜軟體應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表著一個小的業務能力。
  • 歷時一年,我把系統升級成Spring Cloud的微服務架構
    不過也因為此,項目最初的架構設計已經不能滿足現在的需求,並隨著時間的推移,詬病越來越多、越來越嚴重。為了解決這一問題,開發人員也在努力的嘗試各種辦法,但總的來說之前的方式更多是在打補丁,暫時或看上去是解決問題了,實質上並沒有從本質的變化。基於這一情況,這一次我們下定決心,用一定的人力、物力去重新定義系統的架構——基於Spring Cloud實現微服務的架構。
  • 基於微服務和Docker容器技術PaaS雲平臺架構設計(實施原理)
    在系統架構上,PaaS雲平臺主要分為微服務架構、Docker容器技術、DveOps三部分,這篇文章重點介紹微服務架構的實施。實施微服務需要投入大量的技術力量來開發基礎設施,這對很多公司來說顯然是不現實的,別擔心,業界已經有非常優秀的開源框架供我們參考使用。
  • Netflix 微服務架構設計解析
    Netflix 的技術團隊如夢方醒,它需要一個沒有單點故障的更可靠的基礎架構。因此技術團隊管理層做出兩個重要決定,將 IT 基礎架構從自己的IDC遷移到公共雲上,通過改造成微服務架構,用較小的易管理軟體組件替換單體程序。
  • SpringCloud微服務架構篇3:Spring Cloud簡介
    4、微服務的容錯微服務架構的容錯提出了斷路器、服務降級等模式,這些模式都可以有效防止微服務調用失敗而引起的連鎖反應,並且在必要時可以通過這些模式主動實施應用的降級處理,從而保證核心業務的正常運行。所提供的基礎設置,如服務發現、客戶端負載均衡、API網關、微服務容錯、統一配置中心、消息總線及微服務調用監控等,都可以做到一鍵啟動和部署。
  • 微服務架構秘籍:SpringCloud+SpringCloud Alibaba,全網瘋傳
    我們是面臨了什麼問題,導致我們要拋棄單體應用轉向微服務架構?(一)(二)(三)(四)等這5份微服務架構筆記,原版文件都有整理,需要的朋友可免費分享給你,私信我【微服務】立即給你回復。微服務架構秘籍:SpringCloud Alibaba第一 章 微服務介紹1.1 系統架構演變1.2 微服務架構介紹1.3 SpringCloud Alibaba介紹
  • java架構師指南:java語言相關的微服務架構
    1.SpringBoot SpringBoot的設計目的簡化Spring應用程式的初始構造和開發。在2017年,有64.4%的受訪者決定使用SpringBoot,這可以說是最受歡迎的微服務開發框架。利用SpringBoot開發的便利性來簡化分布式系統基礎結構的開發,例如配置中心,註冊,負載平衡等,可以實現一鍵啟動和一鍵部署。
  • 程式設計師必備的15種微服務架構框架
    對於中大型架構系統來說,微服務更加便捷,微服務成為很多企業架構重構的方向,同時也對架構師提出更高的挑戰。目前有很多常用於微服務構建的框架,對於構建微服務架構能夠帶來一些幫助。
  • 程式設計師必備的15種微服務架構框架
    2019年有一個統計說,兩千家企業裡,45%在使用微服務,16%在實驗開發和測試微服務架構,24%在學習微服務準備轉型,只有剩下的15%的企業沒有使用微服務。微服務到底有什麼好呢?微服務在2013年才被提出,短短幾年就有這麼快速的發展。
  • 對微服務架構設計實踐中若干問題的探討
    要確保每個微服務都獨立自治和鬆耦合,那麼微服務從資料庫到邏輯層到前臺全部都要進行縱向拆分。即資料庫的拆分是整個微服務架構設計中的一個關鍵內容。而這裡有一個關鍵思考就是,在微服務實踐中你會看到,實際上你上層的微服務組件的拆分相當來說會更加細,一個不算複雜的業務系統拆分到20到30個微服務組件都是正常情況。
  • 阿里內部價值百萬「微服務架構精髓」限時開源
    前言關於微服務架構網絡上有太多的相關博客和書籍討論,簡單的說就是將單體應用進一步拆分, 拆分成更小的服務,每個服務都是一個可以獨立運行的項目。由SOA架構 -> 微服務架構的轉變,可以理解為什麼微服務架構被廣泛提到並實踐。它解決了什麼問題,帶來了什麼價值?
  • 全面解析 Netflix 的微服務架構設計
    Netflix 意識到,它需要一個沒有單點故障的更可靠的基礎架構。因此它做出兩個重要決定:將 IT 基礎架構從自己的數據中心遷移到公共雲上,並通過微服務架構,用較小的易管理軟體組件替換單體程序。這兩個決定為今天 Netflix 的成功打下了堅實基礎。
  • Java高並發高性能分布式框架從無到有微服務架構設計
    微服務架構模式(Microservice Architect Pattern)。近兩年在服務的瘋狂增長與雲計算技術的進步,讓微服務架構受到重點關注微服務架構是一種架構模式,它提倡將單一應用程式劃分成一組小的服務,服務之間互相協調、互相配合,為用戶提供最終價值。
  • P8架構師傳授的這份在GitHub標星75K的微服務筆記魅力究竟多大?
    ,深入淺出地剖析了其在構建微服務架構中所需的各個基礎設施和技術要點,包括服務治理、容錯保護、API網關、配置管理、消息總線等。、Spring Cloud與Docker高並發微服務架構設計實施 、筆記從架構設計、應用開發和運維部署三個方面出發,對微服務架構設計的實施進行全方位的介紹和詳細說明,在這一過程中將使用一個網際網路平臺的實例展開分析和深入實踐。