1.0 簡介:不可避免的分配法則
本系列的 1.0 版本奠定了基礎,定義了後端工程的角色、工具和初始架構模式。 我們探索了單體應用和微服務、SQL 和 NoSQL、REST 和 GraphQL。 這些知識代表了構建功能應用程序的必要基礎。 然而,本卷講述的是當我們擴展這些應用程序時會發生什麼;當我們的單個服務器變成一個集群時,我們的單個數據庫變成一個集群,我們的進程內調用變成網絡躍點。 這是分佈式系統的領域,它由一套不同的、更嚴格的規則管理。
從單機系統到分佈式系統的轉變並不是複雜性的線性增加;這是一種範式轉變。 在單台機器上成立的假設;可靠組網、零延遲、即時操作;都破碎了。 高級後端工程師的主要目標是構建即使底層環境固有的不可靠性也能正確可靠地運行的系統。
1.1 分佈式計算的八個謬誤
20 世紀 90 年代,L. Peter Deutsch 和 Sun Microsystems 的其他人編制了一系列謬誤;剛剛接觸分佈式應用程序的程序員總是會做出這樣的假設,這會給他們帶來危險。
CAUTION{title=“Eight Fallacies of Distributed Computing”}
- **網絡可靠。 **(事實並非如此。)
- **延遲為零。 **(事實並非如此。)
- **帶寬是無限的。 **(事實並非如此。)
- **網絡是安全的。 **(事實並非如此。)
- **拓撲不會改變。 **(確實會改變。)
- **有一名管理員。 **(有很多。)
- **運輸成本為零。 **(事實並非如此。)
- **網絡是同質的。 **(事實並非如此。) :::在某種程度上,本卷中討論的每種模式、協議和架構都是減輕這些謬論後果的策略。
1.2 高級後端工程路線圖
在此基礎上,我們探索定義現代系統架構的高級主題:
- 第 2 節:高級數據管理和一致性
- 第 3 節:彈性系統設計模式
- 第 4 節:高級異步通信
- 第 5 節:大規模性能工程
- 第 6 節:高級 API 和安全架構
2.0 高級數據管理和一致性
在具有一個數據庫的單服務器應用程序中,數據一致性主要通過 ACID 事務來解決。 在分佈式系統中,一致性成為最困難的挑戰之一。
2.1 一致性譜和 PACELC 定理
CAP 定理描述了網絡分區期間的行為,但 PACELC 定理 提供了更完整的情況:
NOTE{title=“PACELC Theorem”} “如果存在分區(P),分佈式系統必須在可用性(A)和一致性(C)之間進行選擇。否則(E),當系統正常運行時,必須在延遲(L)和一致性(C)之間進行選擇。” :::這迫使人們進行細緻入微的架構討論。 系統在故障期間可能會為了可用性而犧牲一致性,但在正常操作期間優先考慮一致性而不是延遲。
2.2 分佈式事務:Saga 模式
兩階段提交是同步的,不適合微服務。 Saga 模式通過本地事務和補償操作來管理跨服務的數據一致性。
TIP{title=“Saga Pattern Example: E-commerce Order”}
Order Service:創建處於PENDING狀態的訂單,發布ORDER_CREATED事件Payment Service:處理付款,成功時發布PAYMENT_PROCESSEDInventory Service:更新庫存,成功後發布INVENTORY_UPDATED4.“訂單服務”:將訂單更新為“已確認”失敗處理: 如果庫存失敗,支付服務將通過退款進行補償,訂單服務將取消。 :::實施風格:
NOTE{title=“Saga Implementation Approaches”}
- 編排: 服務發布/訂閱事件,無需中央協調員
- 編排: 中央編排器管理 saga 狀態和補償事務
2.3 事件溯源和 CQRS
這些模式構建了高度可擴展和可審計的系統。
- 事件溯源: 存儲不可變事件而不是當前狀態。 當前狀態是通過重播事件得出的。
NOTE{title=“Event Sourcing Example”}
// 而不是存儲餘額:80// 存儲事件序列:[{"type": "AccountCreated", "initialBalance": 0},{“類型”:“DepositMade”,“金額”:100},{“類型”:“提款”,“金額”:20}]// 當前餘額 = 重播事件:::* CQRS(命令查詢職責分離): 將寫入模型與讀取模型分開。
TIP{title=“CQRS Benefits”} *針對寫入與讀取進行優化的不同模型
- 命令和查詢端的獨立縮放
- 具有獨立上下文的更好的領域建模
2.4 後端工程師的數據庫內部結構
了解存儲引擎和復制策略對於性能和可靠性至關重要。
NOTE{title=“MySQL Storage Engines”}
- InnoDB: 適用於 OLTP 工作負載的事務性、符合 ACID 的行級鎖定
- MyISAM: 讀取速度快,表級鎖定,無事務(新應用程序已棄用) :::複製策略:
TIP{title=“Replication Models”}
- Leader-Follower: 所有寫入領導者,從副本讀取(最常見)
- Multi-Leader: 多個節點接受寫入,必須解決複製衝突
- Leaderless(Cassandra 風格): 同時寫入多個節點,仲裁讀取 :::事務隔離級別 (SQL):
NOTE{title=“SQL Isolation Levels”}
- 讀取未提交: 可以讀取未提交的更改(臟讀)
- 讀已提交: 只讀取已提交的更改(可能不可重複讀取)
- 可重複讀取: 事務內行值一致(可能存在幻讀)
- **可串行化:**完全串行執行(一致性最高,性能最低)
3.0 彈性系統設計模式
彈性是指從故障中恢復並繼續運作的能力;優雅地處理故障而不是完全阻止它們。
3.1 斷路器模式(深入)
斷路器監視故障並防止分佈式系統中的級聯故障。
NOTE{title=“Circuit Breaker States”}
- 關閉: 正常運行,請求流經,監控失敗
- 開放: 下游問題快速失敗,重試前超時
- 半開放: 使用單個探測請求測試下游恢復
3.2 艙壁模式
將應用程序組件隔離到池中,以防止單一故障影響整個系統。
TIP{title=“Bulkhead Implementation”} 為每個下游服務使用單獨的線程/連接池。 緩慢的服務 A 不會影響服務 B 的池,從而防止系統完全故障。
3.3 重試和超時模式
對於處理分佈式系統中的瞬態故障至關重要。
CAUTION{title=“Retry Best Practices”}
- 超時: 積極的超時可防止資源耗盡
- 指數退避: 增加重試間隔(1s、2s、4s、8s)
- 抖動: 添加隨機性以防止雷群問題
3.4 速率限制和減載
保護服務免於過載並實現優雅降級。
NOTE{title=“Rate Limiting Strategies”}
- 令牌桶: 請求時累積令牌,使用時刪除
- 漏桶: 以固定速率處理請求,多餘的被丟棄
- 甩負載: 在極端負載下拒絕低優先級請求
4.0 高級異步通信
異步模式是彈性、鬆散耦合的分佈式系統的基礎。
4.1 消息代理與事件日誌
不同的消息傳遞方法具有不同的權衡。
TIP{title=“Message Broker Characteristics”}
- RabbitMQ: 智能路由、工作隊列、消息代理模型
- Apache Kafka: 事件流、持久日誌、多個消費者
4.2 冪等消費者
對於處理消息傳遞系統中的“至少一次”傳遞至關重要。
NOTE{title=“Idempotency Strategy”}
函數處理消息(消息){if (processedMessages.contains(message.id)) {返回; // 跳過重複}// 處理消息流程業務邏輯(消息);// 跟踪已處理的情況(具有業務邏輯的原子性)processedMessages.add(message.id);}
4.3 事務發件箱模式
解決事件驅動系統中的原子數據庫更新和事件發布。
TIP{title=“Transactional Outbox Flow”}
- 更新業務實體並將事件插入單個本地事務中的發件箱 2.消息中繼異步發布事件並標記為已發送
- 保證原子性,無需分佈式事務
- 提供“至少一次”傳遞語義
5.0 大規模性能工程
識別和消除瓶頸的系統紀律。
5.1 緩存模式(深入)
超越基本緩存的高級緩存策略。
NOTE{title=“Caching Pattern Comparison”}
- Cache-Aside: 應用程序代碼管理緩存、延遲加載
- Read-Through: 緩存處理從數據庫加載的數據
- Write-Through: 緩存更新同步更新DB
- 寫回: 緩存更新異步刷新到數據庫 :::雷群緩解:
CAUTION{title=“Thundering Herd Problem”} 當緩存的項目過期時,數千個請求會同時錯過緩存並淹沒數據庫。 解決方案:基於鎖的重新獲取,其中只有第一個請求加載數據,而其他請求則等待。
5.2 並發與並行
性能優化的基本概念。
TIP{title=“Workload Matching”}
- I/O 密集型工作負載: 異步模型(Node.js、asyncio)處理許多並發請求
- 受 CPU 限制的工作負載: 並行性(Go、Java)利用多個核心
5.3 分析和性能調優
你無法優化無法衡量的東西。
NOTE{title=“Performance Profiling”} 使用分析器生成火焰圖來識別:
- 代碼執行路徑中的CPU熱點
- 內存分配模式和洩漏
- I/O 瓶頸和等待時間
6.0 高級 API 和安全架構
用於管理分佈式環境中的複雜性的基礎設施級解決方案。
6.1 API 網關模式
管理客戶端和服務之間通信的單一入口點。
TIP{title=“API Gateway Responsibilities”}
- 路由: 將請求直接發送到適當的微服務
- 身份驗證/授權: 在邊緣驗證憑據
- 速率限制: 強制執行使用策略和限制
- 請求轉換: 調整下游服務的請求
- 可觀察性: 集中記錄和監控
6.2 服務網格
用於安全、快速、可靠的服務間通信的基礎設施層。
NOTE{title=“Service Mesh Components”}
- Sidecar 代理: (Envoy) 處理每個服務的所有入站/出站流量
- 控制平面:(Istio、Linkerd)配置所有 sidecar 代理
- 功能: mTLS、流量管理、分佈式跟踪、可觀察性
6.3 零信任安全
分佈式系統的“從不信任,總是驗證”安全模型。
CAUTION{title=“Zero Trust Principles”}
- 基於身份的身份驗證: 驗證每個請求,無論來源如何
- 最低權限訪問: 授予最低必要權限
- 假設違規: 設計預期內部妥協
6.4 JWT(深入):風險和緩解
了解 JWT 漏洞和安全實施。
CAUTION{title=“JWT Security Issues”}
- 算法混淆攻擊: 欺騙服務器採用弱算法
- 緩解: 配置庫僅接受強算法 (RS256)
- 令牌撤銷: 無狀態令牌無法失效
- 緩解: 在快速緩存中維護撤銷拒絕列表
7.0 結論:有原則的工程師
2.0 版本已涉足分佈式系統工程。 構建有彈性、可擴展的後端系統需要深入了解基本的權衡:延遲與一致性、可用性與正確性、速度與安全性。
高級後端工程師針對故障進行設計,假設網絡敵意,並應用 Sagas、事件溯源、斷路器和服務網格等模式。 最終的技能是對複雜性進行推理;識別故障點、瓶頸和漏洞,以應用適當的緩解策略。