複雜度管理#

架構設計的主要目的是為了解決軟件系統複雜度帶來的問題。理解複雜度的來源和管理方法,是架構師的核心能力。

架構設計的真正目的#

架構設計的主要目的是為了解決軟件系統複雜度帶來的問題。

這個看似簡單的結論,卻是架構設計的指導原則。

常見誤區#

誤區問題
「架構很重要,所以要做」正確的廢話,不知道為何重要
「每個系統都要做架構設計」知其然不知其所以然,容易生搬硬套
「流程要求必須有架構設計」舍本逐末,為了做而做
「為了高效能、高可用」不管三七二十一都要「高」,容易過度設計

正確的理解#

明確「解決複雜度」這個目標後:

  • 新手:心中有數,知道從哪裡下手
  • 老鳥:有的放矢,不會貪大求全
複雜度分析實例

場景:設計一個大學學生管理系統

維度分析結論
效能學生 1~2 萬,訪問頻率低不複雜,MySQL + Nginx 足夠
可擴展功能穩定,變化不大不複雜
高可用宕機 2 小時影響不大不需要負載均衡、異地多活
存儲可靠資料丟失修復困難這是複雜點,需要主備
安全有隱私但非強隱私ACL + 密碼管理即可

結論:主要複雜度在存儲可靠性,架構重點是 MySQL 主備方案。

複雜度的六個來源#

┌─────────────────────────────────────────────────────────┐
│                    複雜度來源                            │
├──────────────┬──────────────┬───────────────────────────┤
│    高效能     │    高可用    │        可擴展             │
├──────────────┼──────────────┼───────────────────────────┤
│    低成本     │     安全     │         規模              │
└──────────────┴──────────────┴───────────────────────────┘

來源一:高效能#

詳見高效能架構設計章節。

核心複雜度

  • 單機:並發模型選擇
  • 集群:任務分配與分解

來源二:高可用#

詳見高可用架構設計章節。

核心複雜度

  • 冗餘方案設計
  • 故障檢測與切換
  • 資料一致性

來源三:可擴展#

詳見可擴展架構設計章節。

核心複雜度

  • 預測哪些會變化
  • 如何隔離或封裝變化

來源四:低成本#

低成本本質上與高效能、高可用衝突,因為後者通常需要更多機器。

低成本通常不是首要目標,而是約束條件。在滿足效能和可用性的前提下,盡量降低成本。

低成本的實作途徑

途徑描述例子
引入新技術用更高效的技術替代Redis 替代 MySQL 做快取
創造新技術自研更適合的方案Facebook 的 HHVM
架構最佳化減少不必要的組件去掉過度設計的中間層

來源五:安全#

安全複雜度分為兩類:

功能安全(防小偷)

  • 本質:系統實作有漏洞
  • 例子:XSS、SQL 注入、CSRF
  • 特點:逐步完善,無法一勞永逸

架構安全(防強盜)

  • 本質:抵禦外部攻擊
  • 例子:DDoS、入侵
  • 方案:防火牆、WAF、流量清洗

互聯網系統的架構安全主要依靠運營商或雲服務商的能力,很少自己實作。

來源六:規模#

量變引起質變,當規模超過一定閾值,複雜度會發生質的變化。

功能規模的複雜度

功能數量增加時,複雜度指數級增長:

3 個功能:複雜度 = 3 + 3 = 6
    ●───●
     \ /
      ●

8 個功能:複雜度 = 8 + 28 = 36
    ●─●─●
    │╲│╱│
    ●─●─●
     ╲│╱
      ●─●

資料規模的複雜度

資料量可能的問題
< 100 萬行單表基本夠用
100 萬 ~ 1000 萬需要索引最佳化
1000 萬 ~ 1 億考慮分表
> 1 億必須分庫分表

MySQL 單表超過 5000 萬行後:

  • 添加索引可能需要數小時
  • 修改表結構同樣耗時
  • 備份時間大幅增加

複雜度分析方法#

步驟一:識別複雜度#

不是所有系統都有所有複雜度,需要根據業務識別主要複雜度。

┌─────────────────────────────────────────────────────────┐
│                    識別複雜度                            │
├─────────────────────────────────────────────────────────┤
│  1. 這個系統最大的技術挑戰是什麼?                        │
│  2. 如果這個問題解決不好,會有什麼後果?                   │
│  3. 業界類似系統是怎麼解決的?                            │
└─────────────────────────────────────────────────────────┘

步驟二:分析複雜度#

針對識別出的複雜度,深入分析其本質。

複雜度分析模板
分析項內容
複雜度類型高效能 / 高可用 / 可擴展 / …
具體表現具體是什麼問題
影響範圍影響哪些功能、哪些用戶
嚴重程度高 / 中 / 低
解決方案備選方案及對比

步驟三:設計架構#

針對複雜度設計架構,而不是為了架構而架構。

flowchart TD
    A[業務需求] --> B[識別複雜度來源]
    B --> C[針對性設計架構]
    C --> D[落地實作]

    B -.- B1((高效能?高可用?可擴展?))
    C -.- C1((只解決識別出的複雜度))

    style A fill:#e3f2fd
    style B fill:#fff3e0
    style C fill:#e8f5e9
    style D fill:#f3e5f5

複雜度管理原則#

原則一:識別主要複雜度#

不要試圖解決所有問題,聚焦主要矛盾。

一個系統通常只有 1~2 個主要複雜度,解決了主要複雜度,其他問題往往迎刃而解或變得不那麼重要。

原則二:按需設計#

需要多少複雜度就設計多少,不多也不少。

情況問題後果
過度設計解決了不存在的問題浪費資源,引入不必要複雜度
設計不足忽略了存在的問題上線後出問題,被迫重構

原則三:適度前瞻#

參考「2 年法則」,適度考慮未來,但不要過度。

          過去              現在              未來
           │                │                │
    ───────┼────────────────┼────────────────┼───────
           │                │                │
           │   設計基於      │   考慮範圍      │
           │   當前需求      │   (2年內)       │

原則四:持續演進#

架構不是一成不變的,需要隨業務發展而演進。

flowchart LR
    subgraph 業務初期
        A[單體應用]
    end
    subgraph 業務發展
        B[垂直拆分<br/>SOA]
    end
    subgraph 業務成熟
        C[微服務<br/>+ 中台]
    end

    A --> B --> C

    style A fill:#ffecb3
    style B fill:#c8e6c9
    style C fill:#bbdefb

常見複雜度場景#

場景一:初創業務#

特點:需求不確定,變化快,團隊小

主要複雜度:可擴展性(適應快速變化)

建議架構

  • 單體應用,快速迭代
  • 保持程式碼整潔,方便後續拆分
  • 不要過早微服務化

場景二:快速增長#

特點:用戶量快速增長,系統壓力大

主要複雜度:高效能

建議架構

  • 加快取
  • 讀寫分離
  • 按需拆分服務

場景三:成熟業務#

特點:業務穩定,對可靠性要求高

主要複雜度:高可用、運維效率

建議架構

  • 完善監控告警
  • 故障自動恢復
  • 灰度發布能力

場景四:企業級應用#

特點:功能複雜,集成需求多

主要複雜度:規模複雜度、集成複雜度

建議架構

  • 領域驅動設計
  • 服務化架構
  • 完善的 API 管理

複雜度評估矩陣#

在做架構決策時,可以用以下矩陣評估:

複雜度當前狀態預期增長優先級方案
高效能P1加快取、水平擴展
高可用P2主從架構
可擴展P2模塊化
低成本--P3雲服務
安全P3基礎防護
規模P3預留拆分空間

本章小結#

主題核心觀點
設計目的解決複雜度問題,而非為了架構而架構
六個來源高效能、高可用、可擴展、低成本、安全、規模
分析方法識別 → 分析 → 設計 → 落地
管理原則識別主要矛盾、按需設計、適度前瞻、持續演進
架構 = 解決複雜度的方案
好的架構 = 用最簡單的方案解決主要複雜度
  • 每次架構設計前,先問自己:「這個系統的主要複雜度是什麼?」
  • 如果答不上來,說明對業務的理解還不夠深入
  • 如果列出了太多複雜度,說明可能過度設計了