iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0

Day 1|System Design 到底在學什麼?從會寫功能,到會設計一個系統

身為一個軟體工程師,我們平常很常把注意力放在「怎麼把功能做出來」。

例如:

  • Login API 要怎麼寫?
  • Database 要怎麼 Query?
  • React Component 要怎麼設計?
  • Authentication 要怎麼實作?

但當系統的使用者從 10 個人變成 10 萬、100 萬,甚至 1,000 萬人之後,我們面對的問題就不再只是「這個功能怎麼寫」。

而會開始變成:

如果同時有 100 萬個 Request 進來怎麼辦?

如果 Database 掛掉怎麼辦?

如果其中一台 Server 掛掉呢?

如果今天的流量突然增加 100 倍呢?

這些問題,就是我們開始進入 System Design(系統設計) 的地方。

這個系列,我希望透過 30 天的時間,從最基礎的 System Design 概念開始,一步一步建立自己設計系統的思考方式。


什麼是 System Design?

先從最簡單的 Web Application 開始。

假設今天我們開發了一個網站,它的架構可能長這樣:

User
  ↓
Frontend
  ↓
Backend API
  ↓
Database

使用者透過 Frontend 操作網站,Frontend 呼叫 Backend API,Backend 再從 Database 取得資料並回傳。

如果今天只有 10 個人在使用,這樣的架構可能完全沒有問題。

但如果我們的產品突然爆紅了呢?

10 users
   ↓
1,000 users
   ↓
100,000 users
   ↓
1,000,000 users
   ↓
10,000,000 users

原本的一台 Backend Server 可能開始處理不完 Request。

Database 可能開始變慢。

世界各地的使用者可能開始覺得圖片載入速度很慢。

甚至只要唯一的一台 Server 掛掉,整個服務就跟著消失。

因此,我們可能開始加入更多東西:

                    ┌── Backend Server #1
User → Load Balancer├── Backend Server #2
                    └── Backend Server #3
                              ↓
                           Cache
                              ↓
                           Database

再繼續擴大,可能還會出現:

  • Load Balancer
  • Cache
  • CDN
  • Database Replication
  • Database Sharding
  • Message Queue
  • Monitoring
  • Failover

這時候問題已經不是「某一個 Function 要怎麼寫」。

而是:

我們要如何設計整個系統,讓它在使用者與資料量不斷增加的情況下,依然能夠穩定、快速、可靠地運作?

這就是我目前對 System Design 最簡單的理解。


Coding vs System Design

我覺得一開始學 System Design 時,一個很重要的觀念,就是把它跟 Coding 的思考層級分開。

Coding 比較常思考

How do I build this feature?

例如今天要實作 Login,我們可能會思考:

POST /login

1. Receive email/password
2. Query user from database
3. Verify password
4. Generate token
5. Return response

這些問題主要關注的是:

「這個功能要怎麼實作?」

System Design 思考的是

How do I build the whole system?

例如同樣是 Login:

如果今天只有 100 個 User,可能很簡單。

但如果今天變成:

1,000,000 users

我們就開始需要問:

  • 如果同時很多人登入怎麼辦?
  • 一台 Server 處理得完嗎?
  • Authentication Service 掛掉怎麼辦?
  • Database 撐得住嗎?
  • Session / Token 要怎麼管理?
  • 要不要使用 Cache?
  • Server 要不要增加到多台?
  • 如何避免惡意使用者一直呼叫 Login API?

所以我目前會把兩者簡單理解成:

Coding
  ↓
How do I build this feature?

System Design
  ↓
How do I design the whole system?

當然,System Design 最後還是要靠程式實作。

兩者並不是互相取代,而是思考的層級不同。


第一個重要概念:Scalability

既然剛剛一直提到「使用者變多」,那就會遇到 System Design 裡非常重要的一個詞:

Scalability(可擴展性)

簡單來說:

當系統的 workload 增加時,系統是否有能力透過增加資源,繼續處理增加的需求。

例如原本系統需要處理:

100 requests / second

後來變成:

1,000 requests / second

甚至:

100,000 requests / second

我們希望系統不會因為流量增加就直接掛掉。

而是可以透過增加資源來應付更多的 Request。


最直覺的方法:換一台更強的 Server?

假設原本只有:

        Requests
            ↓
    ┌──────────────┐
    │    Server    │
    │              │
    │ CPU: 2 cores │
    │ RAM: 4 GB    │
    └──────────────┘

現在 Server 不夠用了。

最直覺的方法可能是:

那我換一台更強的 Server 不就好了?

例如:

CPU: 2 cores  → 16 cores
RAM: 4 GB     → 64 GB

這種做法稱為:

Vertical Scaling(垂直擴展 / Scale Up)

概念非常簡單:

把同一台機器變得更強。

但問題是,一台機器不可能無限升級。

所以另外一種做法是:

                 ┌── Server #1
Requests ────────┼── Server #2
                 ├── Server #3
                 └── Server #4

不是一直升級同一台 Server,而是:

增加更多 Server。

這稱為:

Horizontal Scaling(水平擴展 / Scale Out)

這兩個概念我們之後會再深入討論。

但看到這裡,我馬上產生一個問題:

如果今天有四台 Server:

Server #1
Server #2
Server #3
Server #4

那 User 的 Request 到底要送去哪一台?

總不能讓使用者自己選吧?

這時候就需要另外一個角色幫忙分配流量:

                  ┌── Server #1
                  │
User → ??? ───────┼── Server #2
                  │
                  ├── Server #3
                  │
                  └── Server #4

這個 ???,就是之後會介紹到的 Load Balancer


Scalability 不是唯一要考慮的事情

看到這裡可能會覺得:

那我一直增加 Server 不就好了?

事情當然沒有這麼簡單。

假設今天我們增加到 100 台 Server,但所有 Server 最後都連到同一個 Database:

Server #1  ─┐
Server #2   │
Server #3   ├──→ Database
...         │
Server #100 ┘

這時候 Backend Server 可能不是 Bottleneck 了。

反而變成:

Database 扛不住。

所以 System Design 很有趣的一點就是:

解決了一個 Bottleneck,下一個 Bottleneck 可能又出現。

這也是為什麼後面的文章會慢慢介紹:

Load Balancer
Database Replication
Database Sharding
Cache
CDN
Message Queue
...

這些技術不是為了讓 Architecture Diagram 看起來很厲害,而是每一個 Component 都應該是在解決某個具體問題。


System Design 沒有唯一正解

這也是我覺得學 System Design 很重要的一個觀念。

寫 LeetCode 時,我們通常會希望找到一個相對明確的 Solution。

例如:

Time Complexity: O(n)
Space Complexity: O(1)

但 System Design 通常不是:

「這就是唯一正確的 Architecture。」

而是會一直遇到選擇。

例如:

SQL or NoSQL?

Vertical Scaling or Horizontal Scaling?

Strong Consistency or Eventual Consistency?

Performance or Cost?

Monolith or Microservices?

每一個選擇都有優點,也都有缺點。

所以:

System Design is about trade-offs.

我們真正需要回答的不是:

「哪一個技術比較厲害?」

而是:

「為什麼這個 System 在這個 Requirement 下需要這個技術?」


不要為了 System Design 而 System Design

例如今天只是做一個:

100 users

使用的小型網站。

我們可能根本不需要:

Microservices
Kafka
Redis
Kubernetes
Sharding

如果沒有需求,硬把這些東西全部放進去,反而增加:

  • Development Complexity
  • Infrastructure Cost
  • Maintenance Cost
  • Debugging Difficulty

所以好的 System Design 並不是:

「用了多少厲害的技術。」

而是:

「用了適合這個問題的技術。」

這也是我希望自己在接下來 30 天慢慢建立的能力。


今天學到了什麼?

Day 1 先不急著進入複雜的架構。

今天我想先建立幾個最重要的觀念:

  1. System Design 關注的是整個系統,而不只是單一功能。
  2. 當 User、Traffic、Data 增加時,我們需要考慮 Scalability。
  3. Scaling 可以從 Vertical Scaling 與 Horizontal Scaling 開始理解。
  4. 解決一個 Bottleneck 後,新的 Bottleneck 可能又會出現。
  5. System Design 沒有唯一正解,重要的是理解 Trade-off。
  6. 不要因為某個技術很熱門就使用它,每一個 Component 都應該有存在的理由。

如果要用一句話總結今天:

System Design 不是在背 Architecture,而是在學習面對不同 Requirement 時,如何做出合理的 Engineering Decision。


下一篇

今天我們已經知道,一個系統最簡單可以想成:

User → Frontend → Backend → Database

但其實這張圖省略了非常多東西。

當我們在 Browser 輸入一個網址並按下 Enter:

Browser 到底怎麼知道 Server 在哪裡?

Request 又是怎麼從我們的電腦一路跑到 Backend?

Backend 回傳的資料又是怎麼回到我們的 Browser?

下一篇:

Day 2|當你在瀏覽器輸入網址後發生了什麼?從 DNS 到 Server 的 Request Journey

我們會從一個 Request 的旅程開始,畫出這個系列第一張更完整的 System Architecture。


下一篇
Day2 | 當你在瀏覽器輸入網址後發生了什麼?從 DNS 到 Server 的 Request Journey
系列文
30 天從 Full-Stack Engineer 進化到 System Design:從 0 設計可支撐百萬使用者的系統9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言