讀構建可擴展分散式系統:方法與實踐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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...