架構決策的影響是長期的,需要深思熟慮。
架構設計的本質#
架構設計的本質是做取捨。沒有完美的架構,只有在特定約束下最合適的架構。
喬新亮在《CTO 成長復盤》中分享了架構設計的核心思想:
架構師的角色#
架構師只是個角色,不是個崗位。—— 畢玄
架構師的職責:
- 理解業務需求和技術約束
- 做出關鍵的技術決策
- 指導團隊實施方案
- 為決策的後果負責
架構師需要的能力:
mindmap
root((架構師能力))
💻 技術能力
深度:某個領域的專家
廣度:了解各種技術方案
判斷力:知道什麼時候用什麼
📊 業務理解
理解業務需求
預見未來發展
平衡業務和技術
🗣️ 溝通能力
解釋技術決策給非技術人員
說服團隊接受方案
協調各方利益架構設計的原則#
喬新亮總結的核心原則:
| 原則 | 說明 | 例子 |
|---|---|---|
| 簡單 | 能簡單就不要複雜 | 能用單體就不要微服務 |
| 合適 | 滿足當前需求即可 | 不要過度設計 |
| 演進 | 架構會持續演進 | 為變化留空間 |
| 權衡 | 一切都是取捨 | 性能 vs 成本 vs 複雜度 |
架構決策的方法#
技術選型的考量#
寶玉提出的技術選型框架:
mindmap
root((技術選型))
📋 業務需求
當前功能需求
預期的規模和增長
性能和可用性要求
合規和安全要求
⚙️ 技術因素
技術成熟度
社區活躍度
與現有技術的整合
學習成本
招聘難度
🏢 組織因素
團隊的技術棧和經驗
維護成本
供應商鎖定風險
長期可持續性決策記錄(ADR)#
架構決策記錄(Architecture Decision Record)的格式:
# ADR-001: 選擇 PostgreSQL 作為主數據庫
## 狀態
已接受
## 背景
需要選擇一個主數據庫來支撐業務系統。
當前預估的數據量:XXX
主要訪問模式:XXX
## 決策
選擇 PostgreSQL 作為主數據庫。
## 理由
- 團隊有 PostgreSQL 經驗
- 支援 JSON 類型,便於處理半結構化數據
- 社區活躍,文檔完善
- 開源,無供應商鎖定
## 替代方案
- MySQL:也是可選方案,但團隊經驗較少
- MongoDB:不適合我們的事務需求
## 後果
- 需要培訓部分團隊成員
- 運維需要建立 PostgreSQL 的監控和備份每個重要的架構決策都記錄下來。這樣後人能理解為什麼當時這樣決定,也便於未來重新評估。
高可用設計#
可用性的度量#
喬新亮解釋的可用性標準:
| 可用性 | 年宕機時間 | 月宕機時間 |
|---|---|---|
| 99% (2 個 9) | 3.65 天 | 7.2 小時 |
| 99.9% (3 個 9) | 8.76 小時 | 43.8 分鐘 |
| 99.99% (4 個 9) | 52.56 分鐘 | 4.38 分鐘 |
| 99.999% (5 個 9) | 5.26 分鐘 | 26.3 秒 |
高可用的核心策略#
mindmap
root((高可用))
🔄 冗餘
多實例部署
多機房部署
數據複製
無單點依賴
🛡️ 容錯
故障檢測
自動切換
服務降級
熔斷機制
📊 監控
實時監控
報警機制
快速響應
根因分析異地多活#
畢玄分享了阿里異地多活的經驗:
異地多活是淘寶應對大規模故障的終極方案。
多活的挑戰:
- 數據一致性
- 延遲和同步
- 流量調度
- 成本投入
多活不是簡單的多機房部署,需要從架構層面重新設計。小公司通常不需要,專注做好同城雙活或主備即可。
高性能設計#
性能優化的層次#
喬新亮提出的性能優化框架:
mindmap
root((性能優化))
🏗️ 系統層面
架構優化(緩存、異步、拆分)
數據庫優化(索引、查詢優化、讀寫分離)
緩存策略(多級緩存、緩存更新)
異步處理(消息隊列、批處理)
💻 代碼層面
算法優化
減少 IO
並發處理
內存管理
🔧 運維層面
硬體升級
負載均衡
CDN 加速
數據庫擴展性能優化的原則#
- 先測量再優化:不要憑感覺優化
- 優化瓶頸:找到真正的性能瓶頸
- 投入產出比:優化是有成本的
- 避免過早優化:先讓它工作,再讓它快
80% 的性能問題來自 20% 的代碼。找到那 20%,而不是全面優化。
可擴展性設計#
擴展性的維度#
喬新亮總結的擴展性考量:
| 維度 | 說明 | 方法 |
|---|---|---|
| 水平擴展 | 增加機器來提升容量 | 無狀態設計、負載均衡 |
| 垂直擴展 | 升級單機配置 | 硬體升級、優化 |
| 功能擴展 | 增加新功能 | 模塊化、插件化 |
| 組織擴展 | 更多團隊協作 | 服務拆分、清晰邊界 |
為擴展做準備#
設計時考慮:
├── 無狀態:狀態外移到數據庫/緩存
├── 水平分割:數據可以分片
├── 服務邊界:功能可以拆分
└── 介面穩定:減少變更影響
但不要過度設計:
├── 不需要時不拆分
├── 複雜度有成本
├── 適時重構
└── 滿足當前需求優先設計極限情況#
為什麼要考慮極限情況?#
喬新亮強調:
設計系統時,一定要想清楚:極限情況下會發生什麼?
常見的極限情況:
- 流量突增(10 倍、100 倍)
- 依賴服務故障
- 數據庫連接耗盡
- 消息隊列積壓
- 磁盤空間不足
應對策略#
mindmap
root((極限情況應對))
🚦 限流
請求限流
連接限流
資源配額
優先級調度
⬇️ 降級
功能降級
數據降級
服務降級
靜態化
⚡ 熔斷
快速失敗
自動恢復
半開狀態
隔離故障極限情況下的行為應該是可預期的,而不是完全崩潰。設計時就要想好降級方案。
本章要點#
- 架構的本質是取捨:沒有完美方案,只有合適方案
- 記錄決策:ADR 讓後人理解決策背景
- 高可用三要素:冗餘、容錯、監控
- 性能優化有層次:系統 → 代碼 → 運維
- 為擴展做準備:但不過度設計
- 考慮極限情況:限流、降級、熔斷