讀構建可擴展分散式系統:方法與實踐04應用服務

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

1. 應用服務 1.1. 任何系統的核心都在於實現應用需求的特定業務邏輯 1.2. 服務是可擴展軟體系統的核心 1.2.1. 它們將契約定義為一個API,向客戶端聲明它們的能力 1.3. 應用伺服器高度依賴於編程語言,但通常都會提供多線程編程模型,允許服務同時處理許多請求 1.4. 多服務配置意味著 ...


1. 應用服務

1.1. 任何系統的核心都在於實現應用需求的特定業務邏輯

1.2. 服務是可擴展軟體系統的核心

  • 1.2.1. 它們將契約定義為一個API,向客戶端聲明它們的能力

1.3. 應用伺服器高度依賴於編程語言,但通常都會提供多線程編程模型,允許服務同時處理許多請求

1.4. 多服務配置意味著應用程式可以容忍單個實例的故障

1.5. 無狀態服務允許負載均衡器簡單地將請求重新發送到響應目標,從而輕鬆實現擴展並簡化故障場景

1.6. 大多數負載均衡器採用被稱為粘性會話的特性來支持有狀態服務,但有狀態服務會使得負載均衡和處理故障更加複雜

  • 1.6.1. 不建議在高度可擴展的系統中採用有狀態服務

1.7. Java企業版(JEE)是一種成熟且被廣泛部署的伺服器端技術,它在不同範圍提供了高度抽象的規範,可用於構建豐富而強大的服務

2. 服務設計

2.1. API

  • 2.1.1. Application Programming Interface,應用程式編程介面

  • 2.1.2. 定義了客戶端與伺服器之間的契約

  • 2.1.3. 指定了可能的請求類型、請求所需攜帶的數據以及請求所將獲得的結果

  • 2.1.4. 主要風格還是基於HTTP的,它們通常被歸類為RESTful

  • 2.1.4.1. REST是Roy T. Fielding在他的博士論文中定義的一種架構風格

  • 2.1.4.2. HTTP中API的創建、讀取、更新和刪除(簡稱CRUD)模式

>  2.1.4.2.1. 有效利用了四個HTTP動詞,即POST、GET、PUT和DELETE
  • 2.1.4.3. HTTP PATCH動詞來更新資源的各個屬性
>  2.1.4.3.1. PATCH允許對一個資源的部分屬性進行修改,而PUT則是將一個資源完整地替換成新的資源
  • 2.1.4.4. 有效負載通常被格式化成JSON,當然XML和其他格式也是有可能的

  • 2.1.4.5. HTTP動詞與URI組合在一起定義了API操作的語義

>  2.1.4.5.1. 用URI表示的資源在概念上類似於面向對象設計(OOD)中的對象或實體關係模型(ER模型)中的實體
  • 2.1.5. HTTP API可以採用OpenAPI來聲明

  • 2.1.5.1. SwaggerHub工具是OpenAPI中聲明API的事實標準

  • 2.1.5.2. 該規範是用YAML標記語言來定義的

  • 2.1.6. 一種常見的反模式是Chatty API,它使用多個API請求來執行一個邏輯操作

  • 2.1.7. 對傳遞大負載的HTTP API進行壓縮

  • 2.1.7.1. 所有現代Web伺服器和瀏覽器都支持採用Accept-Encoding和Content-Encoding的HTTP消息頭的壓縮內容

  • 2.1.7.2. 壓縮可以將網路帶寬和延遲減少50%甚至更多

  • 2.1.7.3. 要權衡的是壓縮和解壓縮內容過程中消耗的計算時間,與節省的網路傳輸時間相比一般都很小

2.2. 設計服務

  • 2.2.1. 應用伺服器容器接收請求並將它們路由到適當的處理函數來處理請求

  • 2.2.2. Spring框架利用一組註解來簡化服務代碼,註解定義依賴關係和實現依賴註入

2.3. 狀態管理

  • 2.3.1. 實現可擴展服務的底線是要避免存儲會話的狀態

  • 2.3.2. HTTP是無狀態的協議

  • 2.3.2.1. 意味著每個請求都是獨立執行的,對來自同一個客戶端的早於它執行的請求一無所知

  • 2.3.2.2. 無狀態意味著每個請求都需要是自包含的,不管客戶端之前的行為如何,客戶端要為Web伺服器提供足夠的信息來滿足請求

  • 2.3.3. HTTP支持cookie,就是大家所知的HTTP狀態管理機制

  • 2.3.4. HTTP/2支持流、壓縮和加密,所有這些行為都需要狀態管理

  • 2.3.5. 客戶端和伺服器之間底層的socket連接保持打開狀態,這樣可以分攤同一個客戶端多個請求創建連接的開銷

  • 2.3.5.1. HTTP/1及以上版本的預設行為

  • 2.3.6. 會話狀態指的是在請求之間保留的所有信息,後續請求可以假定服務已保留有關先前交互的信息

  • 2.3.6.1. 如果你有多個客戶端會話都要維護會話狀態,這將占用可用的服務記憶體

>  2.3.6.1.1. 占用的記憶體量將與服務所維護的客戶端數量成正比
  • 2.3.6.2. 還必須註意保持會話狀態的時長
>  2.3.6.2.1. 如果你將此設置為較短的時長,客戶端可能會出現非預期的會話狀態丟失

>  2.3.6.2.2. 如果你將會話超時期限設置得太長,則可能會因為資源不足而降低服務性能
  • 2.3.7. 無狀態服務不會假定之前調用的任何會話狀態已被保留

  • 2.3.7.1. 服務不應該維護來自之前請求的任何信息,每一個請求都可以獨立處理

  • 2.3.7.2. 無狀態服務要求客戶端提供所有必要的信息,以便服務處理請求並提供響應

  • 2.3.8. 任何可擴展的服務都基於無狀態的API

  • 2.3.9. 最重要的設計準則是,對於需要保留與客戶端會話相關的狀態的服務,狀態必須存儲在服務的外部,即外部數據存儲

3. 應用伺服器

3.1. 應用伺服器是可擴展應用程式的核心,它托管了組成應用程式的業務服務

3.2. 其基本作用是接收來自客戶端的請求,將程式邏輯應用於請求,並將請求結果返回給客戶端

3.3. Tomcat是JEE平臺的一個技術子集的開源實現,即Java servlet、Java Server Page(JSP)、Java Expression Language(EL)和Java WebSocket技術

3.4. 如果收到的請求多於伺服器可以排隊和處理的請求,那麼新的TCP/IP連接將被拒絕,客戶端將看到一些錯誤

  • 3.4.1. 最終,超負荷的伺服器可能會因為資源耗盡而拋出異常並崩潰

  • 3.4.2. 花時間調整配置參數以有效處理預期負載是值得的

  • 3.4.3. 系統在達到100%利用率之前往往會降低性能

  • 3.4.3.1. 一旦任何資源(CPU利用率、記憶體使用、網路、磁碟訪問等)接近100%利用率,系統就會表現出難以預測的性能問題

4. 水平擴展

4.1. 擴展系統的核心原則是能夠輕鬆添加新的處理能力來處理增加的負載

4.2. 部署多個無狀態伺服器資源實例,使用負載均衡器在實例之間分配請求

4.3. 無狀態服務副本和負載均衡器都是水平擴展所必需的

4.4. 服務副本部署在它們自己的(虛擬)硬體上

  • 4.4.1. 增加的處理能力使系統能夠處理增加的負載

  • 4.4.2. 水平擴展的目的是創建一個系統,它的處理能力是所有可用資源的總和

  • 4.4.3. 伺服器需要是無狀態的,任何請求都可以發送到任何服務副本來處理

  • 4.4.4. 發送到哪個服務副本是由負載均衡器決定的,它可以使用各種策略來分發請求

  • 4.4.5. 如果負載均衡器可以使每個服務副本保持同樣繁忙,那麼我們就能有效地利用服務副本提供的處理能力

4.5. 如果我們的服務是有狀態的,那麼負載均衡器需要始終將來自同一伺服器的請求路由到同一個服務副本

  • 4.5.1. 由於客戶端會話的持續時間是不確定的,這就可能導致某些服務副本的負載比其他副本高得多

4.6. 水平擴展也提高了可用性

  • 4.6.1. 單服務實例如果失效了,服務就不可用了

  • 4.6.1.1. 單點故障(SPoF)

  • 4.6.1.2. 在任何可擴展的分散式系統中都應避免的一個問題

  • 4.6.2. 多個副本提高了可用性。如果一個副本失敗,可以將請求定向到其他任何副本

5. 負載均衡

5.1. 負載均衡旨在有效利用服務集合的容量來優化每個請求的響應時間

5.2. 目的是避免某些服務超載而其他的服務利用不足

5.3. 客戶端向負載均衡器的IP地址發送請求,負載均衡器將請求重定向到目標服務,並將結果轉發回客戶端

  • 5.3.1. 客戶端永遠不會直接與目標服務通信,這也有利於安全,因為服務可以存在於安全邊界之後並且不會暴露在互聯網上

5.4. 負載均衡器可以是網路級別或應用級別的,通常被稱為四層和七層負載均衡器,分別對應開放系統互連(OSI)參考模型中第4層的網路傳輸層和第7層的應用層

  • 5.4.1. 網路級別的負載均衡器在網路連接級別分發請求,對單個TCP或UDP數據包進行操作

  • 5.4.1.1. 路由決策是根據客戶端IP地址做出的

  • 5.4.1.2. 負載均衡器就會使用一種被稱為網路地址轉換(NAT)的技術,將客戶端請求數據包中的目標IP地址從負載均衡器的地址更改為所選目標的地址

  • 5.4.1.3. 當收到來自目標服務的響應時,負載均衡器將記錄在數據包頭中的源地址從目標服務的IP地址更改為自己的IP地址

  • 5.4.1.4. 除了選擇目標服務和執行NAT功能之外,它們提供的功能很少

  • 5.4.2. 應用級別的負載均衡器會重新組裝整個HTTP請求,並根據HTTP頭的值和消息的實際內容做出路由決策

  • 5.4.2.1. 應用負載均衡器是複雜的反向代理

  • 5.4.2.2. 意味著它們比網路負載均衡器稍微慢一些,但它們提供的強大功能可以用來彌補所產生的開銷

5.5. 負載分配策略

  • 5.5.1. 決定了負載均衡器如何選擇目標服務來處理請求

  • 5.5.2. 迴圈

  • 5.5.2.1. 負載均衡器以迴圈(round robin)方式將請求分發到可用的伺服器

  • 5.5.3. 最少連接數

  • 5.5.3.1. 負載均衡器將新請求分發到打開連接數最少的一個伺服器

  • 5.5.4. HTTP頭欄位

  • 5.5.4.1. 負載均衡器根據特定HTTP頭欄位的內容來引導請求

  • 5.5.5. HTTP操作

  • 5.5.5.1. 負載均衡器根據請求中的HTTP動詞來引導請求

  • 5.5.6. 負載均衡器還可以為服務分配權重

5.6. 健康檢測

  • 5.6.1. 負載均衡器會定期給負載均衡池中的每個服務發送ping命令並嘗試連接以測試服務的健康狀況

  • 5.6.1.1. 這些測試就被稱為健康檢查

  • 5.6.2. 如果與服務的連接只是發生暫時性故障,負載均衡器將會在服務變為健康可用後重新添加進來

5.7. 彈性

  • 5.7.1. 請求負載急劇增加會導致負載均衡器的服務容量達到飽和,導致更長的響應時間,並最終導致請求和連接失敗

  • 5.7.2. 彈性指的是應用動態地提供新的服務容量以處理新增請求的一種能力

  • 5.7.3. 隨著請求負載的增加,新的服務副本會被啟動,負載均衡器將請求定向到新的副本

  • 5.7.4. 隨著負載的減少,負載均衡器則會停止不再需要的服務副本

  • 5.7.5. 彈性要求負載均衡器與應用監控緊密集成,以便定義擴展策略來確定何時增加和減少服務容量

  • 5.7.6. AWS Auto Scaling組是彈性負載均衡的一個實例

  • 5.7.6.1. 定義了集合中服務實例數量的最大值和最小值

  • 5.7.6.2. 負載均衡器將確保組中始終具有最小數量的可用服務,並且永遠不會超過最大數量

  • 5.7.6.3. 有兩種方法可以控制一個組中的副本數量

>  5.7.6.3.1. 一種是基於時間計劃表,相關用例的請求負載的增加和減少是可預測的

>  5.7.6.3.2. 如果無法預測增加的負載峰值,則可以根據應用指標(例如平均CPU和記憶體使用率以及隊列中的消息數量)定義擴展策略來動態控制

  >   5.7.6.3.2.1. 如果超過策略的上限閾值,那麼負載均衡器將啟動一個或多個新的服務實例,直至性能下降到指標閾值以下
  • 5.7.7. 彈性是一個非常關鍵的特性,它允許服務隨著需求的增長而動態擴展

  • 5.7.7.1. 對於負載頻繁波動的高度可擴展系統,它幾乎是一種以最低成本提供所需容量的必備能力

5.8. 會話保持(session affinity)

  • 5.8.1. 會話保持或粘性會話(sticky session)是有狀態服務的負載均衡器特性

  • 5.8.2. 使用粘性會話,負載均衡器會將來自同一客戶端的所有請求發送到同一服務實例

  • 5.8.3. 對於高度可擴展的系統來說,粘性會話可能會有問題

  • 5.8.3.1. 它們會導致負載不均衡的問題,隨著時間的推移,客戶端不會在服務之間均勻分佈

  • 5.8.3.2. 發生負載不均衡的原因是客戶端會話保持的時間不同

>  5.8.3.2.1. 在一個擁有百萬級會話的系統中,持續不斷地創建和銷毀會話,負載不均衡是不可避免的

>  5.8.3.2.2. 這將導致一些服務副本不能被充分利用,而另一些則不堪重負,並可能由於資源耗盡而失敗
  • 5.8.4. 通常,有狀態伺服器會產生在大規模系統中難以設計和管理的問題

  • 5.8.5. 如果服務由於短暫的網路中斷而變慢,負載均衡器會將其從服務組中取出,直到它通過健康檢查或失敗

  • 5.8.6. 無狀態服務提升了可擴展性,簡化了故障場景,並減輕了服務管理的負擔

5.9. 通過負載均衡擴展一組服務可能會導致負載均衡服務所依賴的下游服務或資料庫不堪重負


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

-Advertisement-
Play Games
更多相關文章
  • 此教程適應於以webpack,vue-cli,vite等腳手架構建的vue項目。當然,vue2和vue3都是可以滴。 1. 前提:你的代碼庫已經提交到Github上 如果沒有的話,請到GitHub上新建倉庫,並把你本地的項目提交到GitHub上新建的倉庫里。 具體方法,可以參考我的博客 Git使用記 ...
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:霽明 什麼是CORS CORS(跨域資源共用)是一種基於HTTP頭的機制,可以放寬瀏覽器的同源策略,實現不同功能變數名稱網站之間的通信。 前置知識 同源定義:協議、域 ...
  • 1、使用 Object.entries() 和 Object.fromEntries() // 將對象轉換為數組並轉換回來,以便於操作 const person = { name: 'jack', age: 20 }; const entries = Object.entries(person); ...
  • title: Nuxt Kit 的使用指南:從載入到構建 date: 2024/9/12 updated: 2024/9/12 author: cmdragon excerpt: 摘要:本文詳細介紹了Nuxt Kit的使用方法,包括如何使用loadNuxt載入配置、buildNuxt進行項目構建、l ...
  • 安裝vite npm create vite@latest 你還可以通過附加的命令行選項直接指定項目名稱和你想要使用的模板。例如,要構建一個 Vite + Vue + ts 項目,運行: # npm 7+,需要添加額外的 --: npm create vite@latest my-vue-app - ...
  • codecv —— 一款製作簡歷的工具,幫助你以 Markdown 的簡潔語法快速編寫生成專業的簡歷,並支持轉為 PDF 保存,還提供了海量模板。 ...
  • title: Nuxt Kit 的使用指南:模塊創建與管理 date: 2024/9/11 updated: 2024/9/11 author: cmdragon excerpt: 摘要:本文是關於Nuxt Kit的使用指南,重點介紹瞭如何使用defineNuxtModule創建自定義模塊及inst ...
  • 1. 分散式緩存 1.1. 緩存存在於應用程式的許多地方 1.1.1. 行應用程式的CPU具有高速多級硬體緩存,可以減少相對較慢的主記憶體訪問 1.1.2. 資料庫引擎可以利用主記憶體來緩存數據存儲的內容,這樣在許多情況下查詢就可以不用訪問速度相對較慢的磁碟 1.2. 分散式緩存是可擴展系統的重要組成部 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...