Day 1 我們先認識了什麼是 System Design,也建立了一個最簡單的 Web Application 架構:
User
↓
Frontend
↓
Backend
↓
Database
這張圖很容易理解,但其實省略了很多東西。
例如,當我們打開 Browser,在網址列輸入:
https://example.com
然後按下 Enter。
幾秒鐘後,網站就出現在螢幕上。
看起來只是一個非常簡單的動作,但背後其實發生了一連串的事情:
example.com 的 Server 在哪裡?所以 Day 2,我想先了解:
一個 Request 到底是怎麼完成它的旅程?
先不要急著研究每一個細節。
我們可以先把整個流程簡化成:
User
↓
Browser
↓
DNS
↓
Server IP
↓
建立連線
↓
HTTP Request
↓
Backend Server
↓
Database
↓
HTTP Response
↓
Browser
↓
User 看到畫面
接下來再一步一步拆開。
假設今天我們輸入:
https://example.com/users/123
這是一個 URL(Uniform Resource Locator)。
可以先簡單拆成:
https://example.com/users/123
│ │ │
│ │ └── Path
│ │
│ └── Domain Name
│
└── Protocol
其中 https 是 Protocol,example.com 是 Domain Name,而 /users/123 是我們希望存取的 Resource Path。
但是這時候馬上出現第一個問題:
Browser 只知道
example.com,它要怎麼知道 Server 在哪裡?
這就需要 DNS。
電腦在網路上需要透過 IP Address 找到對應的 Server。
例如:
example.com
↓
93.184.216.34
但對人類來說,example.com 顯然比一串 IP Address 好記很多。
因此我們平常使用 Domain Name,而系統會把 Domain Name 解析成對應的 IP Address。
負責這件事情的就是:
DNS(Domain Name System)
我目前會把 DNS 想像成網路世界的「電話簿」。
Alvin → Phone Number
example.com → IP Address
有了 IP Address,Browser 才知道 Request 應該送去哪裡。
實際上的 DNS Lookup 比下面的例子複雜很多,不過現在可以先用簡化版本理解:
Browser
↓
DNS Resolver
↓
DNS Server
↓
找到 IP Address
↓
Browser
取得 IP Address 後,Browser 終於知道:
「我要跟哪個 Server 建立連線。」
現在 Browser 已經知道 Server 的 IP Address。
接下來就需要跟 Server 建立連線。
HTTP/1.1 和 HTTP/2 通常建立在 TCP 上。
TCP 的全名是:
Transmission Control Protocol
它提供可靠、有順序的資料傳輸。
在傳送 HTTP Request 之前,Client 與 Server 需要先建立 TCP Connection。
因為 HTTP/1.1 和 HTTP/2 本身主要負責「Client 和 Server 要傳什麼資料」,但它們需要底層的傳輸機制把資料可靠地送到對方。
這個角色通常就是 TCP。
可以把它想成:
HTTP
↓
決定「要講什麼」
TCP
↓
負責「怎麼可靠地送過去」
IP
↓
負責「送去哪一台機器」
### TCP Three-Way Handshake
簡化來看:
```text
Client Server
-------- SYN -------->
<----- SYN-ACK -------
-------- ACK -------->
可以把它想像成:
Client:我想建立連線。
Server:收到,我也準備好了。
Client:收到,那我們開始。
完成之後,TCP Connection 就建立起來了。
補充:現代網站也可能使用 HTTP/3。HTTP/3 使用 QUIC,而不是 TCP。不過在建立 System Design 基礎時,可以先從 TCP + HTTP/1.1 / HTTP/2 的模型開始理解。
補充:與TCP相對的UDP 不需要先建立 Connection。
這也是 TCP 和 UDP 最大的差異之一:
| TCP | UDP |
|---|---|
| Connection-oriented | Connectionless |
| 傳資料前要建立 Connection | 不需要先建立 Connection |
| 有 Three-Way Handshake | 沒有 Three-Way Handshake |
| 保證順序 | 不保證順序 |
| 遺失可以重傳 | UDP 本身不負責重傳 |
| Reliability 較高 | Overhead 較低、簡單快速 |
TCP 在傳資料前:
Client Server
------ SYN -------->
<--- SYN-ACK -------
------ ACK -------->
Connection Established
↓
開始傳資料
---
## Step 4:HTTPS 還多了一層 TLS
現在大部分網站使用的不是 `http://`,而是 `https://`。
HTTPS 可以先簡單理解成:
```text
HTTP + TLS
TLS(Transport Layer Security)負責建立安全的加密連線。
因此,如果我們使用 HTTPS,流程可以簡化成:
DNS Lookup
↓
取得 IP Address
↓
建立連線
↓
TLS 建立安全連線
↓
傳送 HTTP Request
TLS 背後還會涉及 Certificate、Encryption、Public Key、Private Key、Certificate Authority 等概念,之後談 Security 時可以再深入。
Day 2 先記住:
HTTPS 使用 TLS 保護 Client 和 Server 之間傳輸的資料。
連線準備完成之後,Browser 終於可以傳送 HTTP Request。
例如:
GET /users/123 HTTP/1.1
Host: example.com
這個 Request 可以理解成:
「Server,我想取得
/users/123這個 Resource。」
常見的 HTTP Methods 包含:
| Method | 常見用途 |
|---|---|
| GET | 取得資料 |
| POST | 建立資料 |
| PUT | 更新 / 取代資料 |
| PATCH | 部分更新資料 |
| DELETE | 刪除資料 |
所以現在 Request Journey 變成:
Browser
↓
DNS
↓
Server IP
↓
Connection
↓
HTTP Request
↓
Backend Server
假設我們的 Backend 使用 Spring Boot。
可能會有一個 API:
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUser(id);
}
當 Server 收到:
GET /users/123
Backend 會根據 HTTP Method 和 Path 找到對應的程式邏輯。
例如:
GET /users/123
↓
UserController
↓
UserService
↓
UserRepository
但 User 的資料通常不會直接存在 Application Server 裡,因此 Backend 接下來可能需要去 Database 找資料。
假設我們使用 PostgreSQL。
Backend 可能執行:
SELECT *
FROM users
WHERE id = 123;
Database 找到資料後,把結果回傳給 Backend。
Browser
↓
Backend Server
↓
Database
↓
Backend Server
Backend 再把資料轉換成適合 API Response 的格式,例如:
{
"id": 123,
"name": "Alvin",
"email": "alvin@example.com"
}
Backend 處理完成之後,就會回傳 HTTP Response。
例如:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 123,
"name": "Alvin"
}
一些常見的 Status Code:
| Status Code | 意義 |
|---|---|
| 200 | OK |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
所以最基本的 Request / Response Model 可以理解成:
Client
│
│ HTTP Request
▼
Server
│
│ HTTP Response
▼
Client
如果 Server 回傳的是 HTML,Browser 就會解析 HTML 並顯示網頁。
如果是 React / Next.js Application,也可能是 Frontend JavaScript 呼叫 Backend API:
React Application
↓
GET /api/users/123
↓
Backend
↓
JSON Response
↓
React 更新 UI
最後使用者看到畫面,整個 Request Journey 就完成了。
當我們輸入:
https://example.com
可以先把背後發生的事情理解成:
1. User 輸入 URL
↓
2. Browser 解析 URL
↓
3. DNS Lookup
↓
4. Domain Name → IP Address
↓
5. Browser 與 Server 建立連線
↓
6. HTTPS 使用 TLS 建立安全連線
↓
7. Browser 傳送 HTTP Request
↓
8. Backend Server 處理 Request
↓
9. Backend Query Database
↓
10. Database 回傳資料
↓
11. Backend 回傳 HTTP Response
↓
12. Browser 處理 Response
↓
13. User 看到畫面
如果畫成一個非常簡化的 Architecture:
DNS
│
Domain → IP
│
▼
User → Browser → Network → Backend Server → Database
▲ │
│ │
└──── HTTP Response ──────┘
目前我們的 Architecture 是:
User
↓
Browser
↓
Backend Server
↓
Database
這裡其實藏著很多問題。
如果只有一台 Server:
User
↓
Server ❌
只要 Server 掛掉,整個服務就無法使用。
這就是一個:
Single Point of Failure(SPOF)
1,000,000 Requests
↓
Server
😵
一台 Server 不一定處理得完。
所以我們可能會想到 Day 1 提到的 Horizontal Scaling:
┌── Server #1
Requests ────────┼── Server #2
└── Server #3
但是馬上又遇到一個問題:
Request 到底要送給哪一台 Server?
Day 1 提到:
System Design 不是為了把很多技術塞進 Architecture,而是每一個 Component 都應該在解決某個 Problem。
當 Traffic 增加,一台 Server 不夠時,我們可能增加多台 Server。
但增加多台 Server 後,又會出現新的問題:
Traffic 增加
↓
一台 Server 不夠
↓
增加多台 Server
↓
Request 要怎麼分配?
↓
需要新的解決方案
這就是我希望在這 30 天建立的 System Design 思考方式:
Problem → Requirement → Solution → Trade-off
而不是單純背 Architecture Diagram。
Day 2 我們從一個看似簡單的動作:
在 Browser 輸入 URL
一路看到:
URL
↓
DNS
↓
IP Address
↓
Connection
↓
TLS
↓
HTTP Request
↓
Backend
↓
Database
↓
HTTP Response
↓
Browser
今天最重要的幾個觀念:
如果用一張圖總結今天:
DNS
│
Domain → IP
│
▼
User → Browser → Network → Backend → Database
▲ │
│ │
└────── Response ─────────┘
下一篇:
Day 3|Vertical Scaling vs Horizontal Scaling:Server 不夠用了怎麼辦?
我們會正式深入兩種 Scaling 方法:
Vertical Scaling
vs
Horizontal Scaling
包含:
最後再一步一步走向 Load Balancer。
Day 2 重點:不要急著背複雜的 Architecture。先理解一個 Request 是怎麼從 User 出發、找到 Server、取得資料,再回到 User 手上的。