讀構建可擴展分散式系統:方法與實踐08微服務

来源:https://www.cnblogs.com/lying7/p/18418506
-Advertisement-
Play Games

1. 微服務 1.1. 微服務的起源可以追溯到2008年左右 1.1.1. 在Amazon,​“兩個比薩原則”成為一個單系統組件團隊規模的管理原則,後來被稱為微服務 1.1.1.1. 每個內部團隊都應該小到可以用兩個比薩餅喂飽 1.1.2. Amazon和Netflix是微服務架構的先驅,他們在20 ...


1. 微服務

1.1. 微服務的起源可以追溯到2008年左右

  • 1.1.1. 在Amazon,​“兩個比薩原則”成為一個單系統組件團隊規模的管理原則,後來被稱為微服務

    • 1.1.1.1. 每個內部團隊都應該小到可以用兩個比薩餅喂飽
  • 1.1.2. Amazon和Netflix是微服務架構的先驅,他們在2009年左右大規模採用了微服務架構

  • 1.1.3. Uber已將其微服務架構發展為基於相關服務的集合(稱為域)

1.2. 認為微服務在某種意義上比服務更小,是對微服務的一種誤解

1.3. 微服務是細粒度、高內聚、松耦合服務的一種設計和部署方法,服務被組合起來滿足系統的需求

  • 1.3.1. 定義特征是它們的範圍,圍繞業務能力組織

  • 1.3.2. 細粒度服務或微服務是獨立部署的,並且必須在必要時相互通信和協調以處理各個系統請求

  • 1.3.3. 微服務架構是分散式系統

1.4. 微服務是一種流行的現代架構風格,在合適的場景中具有大量工程優勢

  • 1.4.1. 每個微服務對系統其他部分來說都是黑盒子,它可以內部選擇最適合團隊和應用程式需求的架構和技術棧

  • 1.4.2. 主要的系統新功能可以構建為微服務並組合到應用程式架構中,同時最小化對系統其餘部分的影響

1.5. 有時微服務並不總是正確的方法

1.6. 採用微服務需要引入新的設計和開發實踐,以創建一組細粒度、內聚的組件來滿足你的應用程式需求

1.7. 微服務之間經常協作,需要進行通信來滿足單個請求

  • 1.7.1. 緩慢的響應會導致調用服務中的背壓,最終一個故障會導致所有相關服務崩潰

1.8. 微服務要求開發過程廣泛自動化

  • 1.8.1. DevOps是一個發展快速且技術豐富的領域,搜索引擎是查找構成現代化DevOps管道的各種構建、配置、測試、部署和監控平臺信息的最佳途徑

2. 轉向微服務

2.1. 基於微服務的架構在很多方面受益於過去10年出現的軟體工程和技術創新的融合

2.2. 單體應用

  • 2.2.1. 自IT系統問世以來,單體架構風格一直主導著企業應用程式

  • 2.2.2. 將應用程式分解為多個邏輯模塊或服務,它們作為單個應用程式構建和部署

  • 2.2.3. 單體架構鼓勵創建可在服務實現之間共用的可重用業務邏輯和DAO

    • 2.2.3.1. DAO映射到資料庫實體,所有服務實現共用一個資料庫
  • 2.2.4. IBM WebSphere和Microsoft.NET等主流平臺都支持將所有服務構建和部署為單個可執行包,即術語“單體”​(完整的應用程式)的來源

    • 2.2.4.1. API、業務邏輯、數據訪問等都包含在一個部署件中
  • 2.2.5. 由於應用程式在一臺(可能非常強大的)伺服器上運行,因此系統和錯誤監控也得到了簡化

  • 2.2.6. 垂直擴展(向上擴展)是提高單體應用響應能力和容量的最簡單方法

  • 2.2.7. 水平擴展(向外擴展)也是可行的

    • 2.2.7.1. 可以提供兩個或多個單體副本,並使用負載均衡器來分發請求

    • 2.2.7.2. 有狀態和無狀態服務都適用,只要負載均衡器支持有狀態設計的會話保持特性

  • 2.2.8. 問題

    • 2.2.8.1. 代碼庫的複雜度

      2.2.8.1.1. 隨著應用程式和工程團隊規模的增長,添加新功能、測試和重構變得越來越困難

      2.2.8.1.2. 技術債務不可避免地會累積

      2.2.8.1.3. 如果沒有持續一致的重構努力來維持架構的完整性和代碼質量,工程就會變得更加困難

    • 2.2.8.2. 水平擴展

      2.2.8.2.1. 你可以通過在多個節點上複製應用程式來水平擴展以增加容量

      2.2.8.2.1.1. 每次都要複製整個應用程式(單體)

      2.2.8.2.2. 隨著請求量的快速增長,它們提供了方案來解決擴展單體工程幾乎不可避免地面臨的挑戰

2.3. 打破巨型單體

  • 2.3.1. 微服務架構將應用程式功能分解為多個獨立的服務,這些服務在必要時進行通信和協調

  • 2.3.2. 每個微服務都是完全獨立的,在需要的地方封裝自己的數據存儲,並提供用於通信的API

  • 2.3.3. 優勢

    • 2.3.3.1. 代碼庫

      2.3.3.1.1. 遵循兩個比薩原則,單個服務的複雜程度不應超過小型團隊可以構建、發展和管理的程度

      2.3.3.1.2. 團隊可以完全自主地選擇自己的開發棧和數據管理平臺

      2.3.3.1.3. 一個設計良好的微服務支持的功能範圍更窄、更加內聚,這會降低代碼的複雜度,加快新功能的開發節奏

      2.3.3.1.4. 按需獨立部署微服務的修訂版

      2.3.3.1.5. 如果微服務支持的API是穩定的,則更改對依賴的服務是透明的

    • 2.3.3.2. 水平擴展

      2.3.3.2.1. 可以通過擴展單個微服務來滿足請求量和延遲要求

      2.3.3.2.2. 其他輕負載的服務可以簡單地在單個節點上運行或以低成本進行複製,以消除單點故障並提高可用性

      2.3.3.2.3. 如何將系統功能分解為單獨的服務,是轉向微服務架構的關鍵設計決策之一

      2.3.3.2.3.1. DDD(Domain-Driven Design,領域驅動設計)提供了一種合適的方法來識別微服務

      2.3.3.2.3.2. 微服務必須自包含的性質可以很好地映射到DDD中有界上下文的概念

  • 2.3.4. 微服務本質上是分散式的,總有一個平衡的考量

    • 2.3.4.1. 需要分析和調整領域模型的純度,以滿足分散式通信的成本以及系統管理和監控的複雜性

    • 2.3.4.2. 在耦合的微服務之間複製數據

      2.3.4.2.1. 服務能夠在本地訪問它需要的數據,從而簡化設計並減少數據訪問響應時間

      2.3.4.2.2. 複製數據也需要權衡其利弊

      2.3.4.2.2.1. 需要額外的存儲容量和開發工作來確保所有重覆數據的一致性狀態

      2.3.4.2.2.2. 當數據發生變化時,可以立即啟動數據副本的更新,以儘量減少重覆數據不一致的時間間隔

      2.3.4.2.2.3. 如果業務上下文允許,可以運行定期複製(例如,每小時或每天)​,可能是在請求負載較低時調用計劃任務執行

      2.3.4.2.2.4. 隨著應用程式對性能和可擴展性的需求不斷增長,與系統重大重構所帶來的問題相比,複製數據的成本和複雜性通常很小

  • 2.3.5. 部署微服務

    • 2.3.5.1. 為了支持頻繁更新並從小型團隊提供的靈活性中獲益,你需要能夠簡單快速地部署新的微服務版本

    • 2.3.5.2. 無伺服器處理平臺是一種有吸引力的微服務部署方法

      2.3.5.2.1. 微服務可以在你選擇的無伺服器平臺上構建,並公開API

    • 2.3.5.3. 無伺服器平臺的優點

      2.3.5.3.1. 部署簡單

      2.3.5.3.1.1. 只需將微服務的新可執行包上傳到為函數配置的端點

      2.3.5.3.2. 按使用量付款

      2.3.5.3.2.1. 如果你的服務只有少量請求,那麼你的成本會很低,甚至為零

      2.3.5.3.3. 易於擴展

      2.3.5.3.3.1. 你選擇的平臺會處理函數的擴展

    • 2.3.5.4. 當你將所有微服務都部署到無伺服器平臺上時,你將為客戶端暴露多個需要被調用的端點

      2.3.5.4.1. 將後端更改直接暴露給客戶端從來不是一個好主意

    • 2.3.5.5. API網關模式

      2.3.5.5.1. 將客戶端與實現應用功能的微服務的底層架構隔離開來

      2.3.5.5.2. NGINX Plus

      2.3.5.5.3. Kong

      2.3.5.5.3.1. Kong API網關是無狀態的,因此可以部署多個實例並使用負載均衡器分發請求

      2.3.5.5.4. 特定雲供應商的托管產品

      2.3.5.5.5. 以毫秒級低延遲將傳入的客戶端API請求代理到實現API的後端微服務

      2.3.5.5.5.1. 由API網關處理的面向客戶端的API與後端微服務API之間的映射是通過管理工具或配置文件執行的

  • 2.3.6. 微服務原則

    • 2.3.6.1. 圍繞業務領域進行建模

      2.3.6.1.1. 有界上下文的概念為微服務的範圍提供了一個起點

      2.3.6.1.2. 在微服務之間存在耦合併且可能引入性能開銷的情況下,可能需要重新考慮業務領域邊界

    • 2.3.6.2. 高度可觀測

      2.3.6.2.1. 監控每項服務對於確保它們按預期運行、以低延遲處理請求以及記錄錯誤情況至關重要

      2.3.6.2.2. 在分散式系統中,可觀測性是高效運行的基本特征

    • 2.3.6.3. 隱藏實現細節

      2.3.6.3.1. 微服務是黑盒子

      2.3.6.3.2. 它們的API是其保證支持的契約,但是API內部如何執行不會對外公開

    • 2.3.6.4. 全面去中心化

      2.3.6.4.1. 處理需要多次調用下游微服務的客戶端請求,它們通常被稱為工作流

    • 2.3.6.5. 隔離故障

      2.3.6.5.1. 一個微服務的故障不應傳播到其他微服務並導致應用程式崩潰

    • 2.3.6.6. 獨立部署

      2.3.6.6.1. 每個微服務都應該是可獨立部署的,以便團隊能夠在不依賴於其他團隊進度的情況下進行增強和修改

    • 2.3.6.7. 自動化文化

      2.3.6.7.1. 想要從微服務獲得好處,開發和DevOps的工具及實踐是絕對必要的

      2.3.6.7.2. 自動化使得修改已部署的系統變得更快、更可靠

    • 2.3.6.8. 工作流

      2.3.6.8.1. 編製和編排通常用於實現需要訪問多個微服務的用例

    • 2.3.6.9. 點對點編排

      2.3.6.9.1. 所需的微服務之間直接通信即可滿足請求

      2.3.6.9.2. 每個自治微服務共用處理工作流的責任和知識

      2.3.6.9.3. 通信可以是同步的,也可以是非同步的

    • 2.3.6.10. ⑩集中編製

      2.3.6.10.1. 實現工作流的邏輯被嵌入單個組件中,通常是專用的微服務

      2.3.6.10.2. 該服務與域服務通信並將結果發送回用戶

      2.3.6.10.3. 兩種方法都需要權衡取捨

3. 微服務的彈性

3.1. 分散式系統的一個老生常談的話題是,在絕大多數時間里,系統運行不會出現災難性錯誤

  • 3.1.1. 受益於快速可靠的網路、很少崩潰的機器和磁碟、用於托管微服務及進行消息傳遞的基礎平臺和資料庫非常強大

  • 3.1.2. 你的系統仍然必須為可能發生的間歇性故障做好準備,通常是在最不方便的時候

3.2. 級聯故障

  • 3.2.1. TCP請求將超時並向調用方拋出錯誤

  • 3.2.2. 級聯故障的潛在本質是,它們是由所依賴的服務響應緩慢觸發的

  • 3.2.3. 如果下游服務只是由於系統崩潰或暫時性網路故障而失敗或不可用,調用者會立即收到錯誤並可以做出相應的響應

  • 3.2.4. 對於逐漸變慢的服務,情況並非如此

    • 3.2.4.1. 請求返回結果,只是響應時間更長

    • 3.2.4.2. 如果不堪重負的組件繼續受到請求的轟炸,它就沒時間恢復並且響應時間繼續增長

    • 3.2.4.3. 這種情況通常會因客戶端在請求失敗時立即重試而加劇

      3.2.4.3.1. 立即重試在不堪重負的微服務上維持負載,帶來的結果是可預測的,即另一個異常

      3.2.4.3.2. 重試只是保持壓力

      3.2.4.3.3. 在兩次重試之間插入不斷增加的延遲

      3.2.4.3.3.1. 有助於減輕下游的負載,但這個延遲會計入調用者所經歷的延遲,因此通常無法解決問題

  • 3.2.5. 級聯故障在分散式系統中很常見

    • 3.2.5.1. 無論是由不堪重負的服務引起,還是由錯誤情況(例如應用程式代碼錯誤或網路問題)引起,你都需要採取明確的步驟來防範它們
  • 3.2.6. 避免級聯故障的模式包括使用超時和斷路器發起快速失敗

  • 3.2.7. 快速失敗模式

    • 3.2.7.1. 服務慢的核心問題是它們會長時間占用系統資源來處理請求

    • 3.2.7.2. 請求線程會暫停,直至它收到響應

    • 3.2.7.3. 少量請求花費的時間比平均響應時間長得多

      3.2.7.3.1. 使用百分位數來量化慢速請求的百分比

      3.2.7.3.2. 百分位數提供了比平均值更豐富、更準確的微服務響應時間視圖

    • 3.2.7.4. 伺服器的垃圾回收、資料庫爭用、過多的上下文切換、系統頁面錯誤和網路請求丟失都是造成這種長尾的常見原因

    • 3.2.7.5. 長響應時間從來都不是好事,無論是技術上還是用戶感受上

      3.2.7.5.1. 消除長響應時間的常見方法是快速失敗

      3.2.7.5.1.1. 當請求花費的時間超過某個預設的時間限制時,客戶端不會等待它完成,而是會向其調用者返回一個錯誤

      3.2.7.5.1.2. 在伺服器上啟用節流

3.2.7.5.1.2.1. 如果請求負載超過某個閾值,則立即使請求失敗並返回HTTP503錯誤

3.2.7.5.1.2.1.1. 這向客戶端表明該服務不可用

  • 3.2.7.6. 節流或限制速率是許多負載均衡器和API網關技術中可用的功能

    3.2.7.6.1. 當達到定義的限制時,負載均衡器將拒絕請求,保護它控制的資源免於過載

    3.2.7.6.1.1. 這使服務能夠以一致的低響應時間處理請求

    3.2.7.6.2. 一種稍微複雜的方法可以使用滑動視窗演算法跟蹤平均響應時間或P99等指標

  • 3.2.7.7. 請求失敗時還需要考慮一件事

    3.2.7.7.1. 微服務的一個原則是故障隔離

    3.2.7.7.2. 這意味著部分系統的故障不會導致整個應用程式不可用

  • 3.2.8. 斷路器模式

    • 3.2.8.1. 如果微服務由於過載或網路不穩定而開始拋出錯誤,那繼續向API發送請求是毫無意義的

    • 3.2.8.2. 可以使用斷路器模式來實現這個功能,它可以保護遠程端點在某些錯誤情況發生時不會不堪重負

      3.2.8.2.1. 客戶端可以使用斷路器來保護伺服器免於過載

      3.2.8.2.2. 斷路器配置為監視某些條件,例如端點的錯誤響應率或每秒發送的請求數

    • 3.2.8.3. 對於幾乎肯定會失敗的操作,斷路器是減少資源使用率的重要方式

    • 3.2.8.4. 當服務(有望)恢復時,斷路器會自動重置並恢復正常操作

    • 3.2.8.5. 斷路器對於故障隔離非常有效

      3.2.8.5.1. 它們保護客戶端免受依賴服務的錯誤操作影響,並允許服務恢復

      3.2.8.5.2. 在讀取密集型場景中,當斷路器打開時,請求通常可以返回預設或緩存的結果

      3.2.8.5.2.1. 有效地向客戶端隱藏了故障,並且不會降低服務吞吐量和響應時間

    • 3.2.8.6. 請確保已將斷路器觸發器綁定到監控和日誌記錄基礎架構中,以便診斷故障原因

3.3. 艙壁模式

  • 3.3.1. 艙壁(bulkhead)一詞的靈感來自大型造船實踐

  • 3.3.2. 船體內部被分成幾個物理分區,確保在船體的一部分發生泄漏時只有一個分區被淹沒,船會繼續漂浮,這是相當重要的

  • 3.3.3. 艙壁是一種損害限制策略

    • 3.3.3.1. 微服務中預留一定數量的線程來處理特定的請求

    • 3.3.3.2. 艙壁模式將遠程資源調用隔離在它們自己的線程池中,故單個過載或失敗的服務不會消耗應用伺服器中可用的所有線程

  • 3.3.4. 可用於確保在對微服務中某個API的請求激增期間,不會耗盡所有可用的資源

  • 3.3.5. 通過設置應用伺服器中特定API可以要求的最大線程數量限制,可以保證其他API的處理能力


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • duxapp是基於Taro二次開發的模塊化框架 使用這個框架,結合框架提供的UI庫和工具庫,能幫助你快速且高質量的完成項目,且能實現同時開發小程式、H5、APP(React Native),並且保證各個端的一致性 ...
  • 雲設計模式介紹以及它們如何幫助應對分散式計算的謬誤 作為構建分散式系統的軟體工程師,我們經常遇到諸如不可靠的網路、延遲問題和安全問題等挑戰。"分散式計算的謬誤"描述瞭如果未解決,可能導致系統故障的常見誤解。但認識到這些陷阱只是開始。真正的問題是:我們如何有效地剋服它們?這就是雲設計模式發揮作用的地方 ...
  • 1. Redis 1.1. 2009年首次發佈 1.1.1. 更註重原始性能和簡單性,而不是數據安全性和一致性 1.2. 主要吸引力在於它能夠同時充當分散式緩存和數據存儲 1.3. 維護一個記憶體中的數據存儲,也稱為數據結構存儲(data structure store) 1.4. 配置Redis將每 ...
  • 大家好,我是湯師爺~ 今天聊聊SaaS業務架構的業務能力分析。 業務能力概述 簡單來說,業務能力是企業“做某事的能力”。 業務能力描述了企業當前和未來應對挑戰的能力,即企業能做什麼或需要做什麼。業務能力建模的關鍵在於定義了企業做什麼,而不是如何做(由業務流程描述)。 以人才招聘為例,大多數公司都需要 ...
  • 1. 強一致性 1.1. 最終一致資料庫通過跨多台機器分區和複製數據集來獲得可擴展性,其代價是要跨副本維持強數據一致性以及允許衝突寫入 1.1.1. 在更新數據對象後,不同的客戶端可能會看到該對象的舊值或新值,直到所有副本都收斂到最新值 1.2. 另一類分散式資料庫提供一種可替代的模型,即強一致性數 ...
  • 1. 最終一致性 1.1. 在一些應用領域,通常談論的是銀行和金融行業,最終一致性根本不合適 1.2. 事實上,最終一致性在銀行業已經使用了很多年 1.2.1. 支票需要幾天時間才能在你的賬戶上進行核對,而且你可以輕鬆地開出比賬戶餘額多的支票 1.2.2. 當處理檢查並建立一致性後,你才能看到一些後 ...
  • 大家好,我是湯師爺~ 今天聊聊SaaS架構中的流程架構分析。 業務流程的概念 業務流程是企業為實現目標而制定的一套系統化的工作方法。它由一系列有序的業務活動組成,按照既定規則將資源(輸入)轉化為有價值的結果(輸出)。這一過程需結合企業的具體情況和可用資源,旨在為客戶創造價值,同時達成企業目標。 通過 ...
  • 1. 可擴展資料庫基礎 1.1. 絕大多數應用程式都是基於關係資料庫技術構建的 1.2. 資料庫必須存儲大量數據,為分佈在全球的客戶端提供快速的查詢響應,並且全天候可用 1.3. NoSQL資料庫採用簡單的數據模型,可以複製和分區以支持海量數據集和請求量 1.4. Facebook以使用MySQL管 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...