測驗:設計需求與網路基礎 — CAP 定理、延遲與通訊協定
共 5 題,點選答案後會立即顯示結果
1. CAP 定理中的三個字母分別代表什麼?
2. DNS 的主要功能是什麼?
3. 在高速公路的比喻中,「車道數」對應到系統設計中的哪個指標?
4. 為什麼串流影片通常使用 UDP 而不是 TCP?
5. 一個銀行交易系統在網路分區發生時,選擇拒絕服務也不允許資料不一致。這個系統屬於 CAP 中的哪種類型?為什麼?
**系列**:系統設計白話文(第 2 篇,共 5 篇)
**難度**:L2-進階
**前置知識**:【系統設計白話文】#01 電腦架構全景圖
**影片來源**:freeCodeCamp — *System Design Concepts Course and Interview Prep* by Hayk Simonyan
這篇在講什麼?
上一篇我們看了單台電腦的架構。但真實世界的系統不會只有一台機器 — 它們是分散在多台伺服器上、透過網路互相溝通的。
這篇要回答一個核心問題:當系統分散到多台機器上,會遇到什麼新問題?
讀完後你會看懂:
- 為什麼分散式系統「不可能同時要快、要穩、又要一致」(CAP 定理)
- 「延遲」和「吞吐量」到底在量什麼
- TCP 和 UDP 這兩個你一定聽過的協定差在哪
- 你在瀏覽器輸入網址後,DNS 怎麼幫你找到伺服器
一、CAP 定理:三選二的殘酷現實
一句話說明
分散式系統在「一致性、可用性、分區容錯」三個好處裡,最多只能同時保證兩個。
三個名詞翻譯
| 英文 | 中文 | 白話意思 |
|---|---|---|
| Consistency | 一致性 | 不管問哪台伺服器,拿到的資料都一樣 |
| Availability | 可用性 | 不管什麼時候發請求,系統都會回應 |
| Partition Tolerance | 分區容錯性 | 就算伺服器之間斷線了,系統還是能運作 |
用銀行 ATM 的例子秒懂
想像你有一個銀行帳戶,存了 10,000 元。這個銀行在台北和高雄各有一台 ATM,兩台的資料要保持同步。
正常情況:你在台北 ATM 領了 3,000 元,兩台 ATM 馬上同步,餘額都顯示 7,000 元。三個好處全都有。
但如果台北和高雄的網路斷了呢?(這就是「分區」發生了)
這時銀行只有兩個選擇:
選項 A:選一致性(CP)
─────────────────────
台北 ATM:「網路斷了,我無法確認資料是否最新,
所以我拒絕讓你領錢。」
結果:資料一定正確,但你用不了 → 犧牲可用性
選項 B:選可用性(AP)
─────────────────────
台北 ATM:「網路斷了,但我還是讓你領錢。
等網路恢復再同步。」
結果:你隨時可以用,但可能兩台餘額暫時不一樣 → 犧牲一致性
為什麼不能三個都要?
因為分區(P)在真實網路中一定會發生 — 網路線會斷、路由器會掛。所以 P 幾乎是必選的,你真正在選的是 C 或 A。
真實世界的選擇:
CP 系統(一致性 + 分區容錯)
├── 銀行交易系統 → 寧可暫時不能用,也不能算錯帳
├── 分散式鎖 → 要確保同時只有一個人拿到鎖
└── 例子:MongoDB(預設)、HBase
AP 系統(可用性 + 分區容錯)
├── 社群媒體的按讚數 → 暫時少顯示幾個讚沒關係
├── DNS 系統 → 寧可回傳舊資料也不要沒回應
└── 例子:Cassandra、DynamoDB
Vibe Coder 檢查點
當你看到架構文件提到 CAP 時:
- [ ] 這個系統選的是 CP 還是 AP?
- [ ] 資料「暫時不一致」對使用者的影響大嗎?(金錢交易 vs 按讚數)
- [ ] 系統用了什麼機制來處理網路分區後的資料同步?
二、吞吐量與延遲:兩個常被搞混的指標
一句話說明
延遲是「一件事要多久才完成」,吞吐量是「同一時間能處理多少件事」。
高速公路比喻
延遲(Latency)= 開車從 A 到 B 要多久
例:台北到台中 2 小時
吞吐量(Throughput)= 高速公路同時能跑幾台車
例:四線道 = 每小時通過 4,000 台車
關鍵觀念:加寬車道(提高吞吐量)不會讓每台車開更快(降低延遲)。這是兩個獨立的維度。
對應到系統設計
| 指標 | 衡量什麼 | 單位 | 比喻 |
|---|---|---|---|
| Latency(延遲) | 一個請求從發出到收到回應的時間 | 毫秒(ms) | 車程時間 |
| Throughput(吞吐量) | 系統每秒能處理多少請求 | RPS(requests/sec) | 車道數 |
你會在文件裡看到的寫法
# 效能報告常見格式
延遲指標:
P50 = 120ms ← 50% 的請求在 120ms 內完成(中位數)
P95 = 350ms ← 95% 的請求在 350ms 內完成
P99 = 800ms ← 99% 的請求在 800ms 內完成
吞吐量指標:
平均 RPS = 15,000 ← 每秒處理 15,000 個請求
峰值 RPS = 42,000 ← 高峰時每秒 42,000 個
Code language: PHP (php)為什麼要看 P95、P99? 因為平均值會騙人。如果 99% 的使用者等 100ms,但 1% 的使用者等 10 秒,平均值看起來「只有 200ms」,但那 1% 的人體驗很差。
三、SLO 與 SLA:對使用者的承諾
一句話說明
SLO 是「我們系統要達到的效能目標」,SLA 是「我們對客戶承諾的效能,做不到就賠錢」。
名詞翻譯
| 縮寫 | 全名 | 白話意思 |
|---|---|---|
| SLI | Service Level Indicator | 實際量到的數字(例:今天 uptime 是 99.95%) |
| SLO | Service Level Objective | 團隊內部設的目標(例:我們的目標是 99.9% uptime) |
| SLA | Service Level Agreement | 寫在合約裡的承諾(例:低於 99.9% 就退費) |
99.9% Uptime 到底是多少停機時間?
99% 的 uptime = 每年可停機 3.65 天 ← 相當寬鬆
99.9% 的 uptime = 每年可停機 8.76 小時 ← 大部分雲端服務的標準
99.99% 的 uptime = 每年可停機 52.6 分鐘 ← 很嚴格
99.999%的 uptime = 每年可停機 5.26 分鐘 ← 電信等級,極少系統能做到
白話翻譯:每多一個 9,難度就高一個量級,成本也是。
Vibe Coder 檢查點
當你在選雲端服務或讀架構文件時:
- [ ] 這個服務的 SLA 是幾個 9?
- [ ] SLA 裡的「可用性」是怎麼定義的?(有些服務算的是月平均,不是每分鐘)
- [ ] 違反 SLA 的補償是什麼?(通常是服務額度,不是現金)
四、IP 位址:網路世界的門牌號碼
一句話說明
IP 位址是每台連上網路的裝置的唯一識別碼,就像門牌號碼讓郵差知道信要送去哪。
兩種格式
IPv4:203.0.113.42
↑ 四組數字,每組 0-255,用點分隔
↑ 總共約 43 億個地址(已經不夠用了)
IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334
↑ 八組十六進位數字,用冒號分隔
↑ 地址數量多到可以給地球每粒沙子分一個
Code language: CSS (css)IP 封包的結構(知道就好)
每次你的電腦發送資料時,資料前面會加上一個「信封」(IP 標頭):
┌─────────────────────────────────┐
│ IP 標頭 │
│ ┌───────────┬───────────────┐ │
│ │ 來源 IP │ 203.0.113.42 │ │ ← 寄件人地址
│ │ 目的 IP │ 198.51.100.1 │ │ ← 收件人地址
│ │ TTL │ 64 │ │ ← 最多經過 64 個路由器就丟棄
│ │ 協定 │ TCP 或 UDP │ │ ← 用哪種方式傳送
│ └───────────┴───────────────┘ │
├─────────────────────────────────┤
│ 資料內容 │
│ (你真正要傳的東西) │
└─────────────────────────────────┘
Code language: CSS (css)白話翻譯:IP 標頭就是信封上的寄件/收件地址,讓網路知道這包資料從哪來、要去哪。
五、TCP vs UDP:兩種資料傳輸方式
一句話說明
TCP 是掛號信(慢但保證送到),UDP 是傳單(快但可能掉)。
對照比較
| 特性 | TCP | UDP |
|---|---|---|
| 全名 | Transmission Control Protocol | User Datagram Protocol |
| 比喻 | 掛號信 | 傳單 |
| 保證送達? | 是,沒收到會重傳 | 不保證 |
| 資料順序? | 保證按順序到達 | 不保證順序 |
| 速度 | 較慢(有額外確認步驟) | 較快(發了就走) |
| 適合場景 | 網頁、檔案下載、Email | 串流影片、遊戲、視訊通話 |
TCP 的三次握手(最小範例)
TCP 在傳資料之前,雙方要先「握手」確認彼此都在:
你的電腦 伺服器
│ │
│── 1. SYN:「嘿,在嗎?」──→ │
│ │
│←─ 2. SYN-ACK:「在,你呢?」│
│ │
│── 3. ACK:「我也在,開始吧」→│
│ │
│←──── 正式開始傳資料 ────→ │
白話翻譯:就像打電話 — 你先說「喂」,對方回「喂,聽到了」,你再說「好,我要開始講了」。確認雙方都準備好了才開始講正事。
UDP:發了就走
你的電腦 伺服器
│ │
│── 資料 1 ──────────────→ │ ✓ 收到
│── 資料 2 ──────────────→ │ ✗ 掉了(沒人知道)
│── 資料 3 ──────────────→ │ ✓ 收到
│── 資料 4 ──────────────→ │ ✓ 收到
為什麼串流影片用 UDP? 因為看影片時,掉一兩個畫面你根本感覺不到,但如果用 TCP 一直重傳掉落的封包,影片就會卡頓。快比完整更重要。
你會在程式碼裡看到的樣子
當 AI 幫你寫網路程式時,你可能會看到這些:
import socket
# TCP 連線 — 看到 SOCK_STREAM 就是 TCP
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# ↑ STREAM = 串流 = TCP
# UDP 連線 — 看到 SOCK_DGRAM 就是 UDP
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ↑ DGRAM = Datagram = UDP
Code language: PHP (php)必看懂:SOCK_STREAM = TCP,SOCK_DGRAM = UDP。名字不直覺,但出現頻率很高。
Vibe Coder 檢查點
當你看到網路相關的程式碼或架構時:
- [ ] 用的是 TCP 還是 UDP?(看 STREAM 或 DGRAM)
- [ ] 如果是即時應用(遊戲、視訊),用 UDP 是合理的
- [ ] 如果是要保證資料完整(API 呼叫、檔案傳輸),應該用 TCP
六、DNS:網路世界的電話簿
一句話說明
DNS 把人看得懂的網址(google.com)翻譯成電腦看得懂的 IP 位址(142.250.185.14)。
為什麼需要 DNS?
你記得住:google.com
你記不住:142.250.185.14
DNS 的工作:幫你把 google.com 翻譯成 142.250.185.14
Code language: CSS (css)DNS 解析流程(完整版)
當你在瀏覽器輸入 www.example.com 後,背後發生了這些事:
步驟 1:先查本機快取
你的電腦:「我之前查過 www.example.com 嗎?」
→ 有快取 → 直接用,結束
→ 沒快取 → 繼續往下問
步驟 2:問 DNS 遞迴解析器(通常是你的 ISP 或 8.8.8.8)
解析器:「我知道 www.example.com 的 IP 嗎?」
→ 有快取 → 直接回覆
→ 沒快取 → 幫你去問
步驟 3:問根域名伺服器(Root Server)
解析器:「.com 的管理者是誰?」
根伺服器:「去問 .com 頂級域名伺服器,地址是 xxx」
步驟 4:問 .com 頂級域名伺服器(TLD Server)
解析器:「example.com 的管理者是誰?」
TLD 伺服器:「去問 example.com 的權威域名伺服器,地址是 yyy」
步驟 5:問權威域名伺服器(Authoritative Server)
解析器:「www.example.com 的 IP 是什麼?」
權威伺服器:「是 93.184.216.34」
步驟 6:回傳結果
解析器把 93.184.216.34 回傳給你的電腦,
你的電腦把結果存進快取,下次就不用再問了。
Code language: CSS (css)簡化版一張圖
你的瀏覽器
│
│ www.example.com 的 IP 是?
▼
DNS 遞迴解析器(中間人)
│
├──→ 根伺服器:「.com 去找 TLD 伺服器」
├──→ TLD 伺服器:「example.com 去找權威伺服器」
└──→ 權威伺服器:「IP 是 93.184.216.34」
│
│ 93.184.216.34
▼
你的瀏覽器 → 連線到 93.184.216.34
Code language: CSS (css)你可以在終端機試試看
# 查詢一個網域的 IP(你可以直接在終端機跑)
nslookup google.com
# 更詳細的查詢(會顯示整個 DNS 查詢路徑)
dig google.com
Code language: CSS (css)# nslookup 的輸出大概長這樣:
Server: 8.8.8.8 ← 你用的 DNS 伺服器
Address: 8.8.8.8#53 ← DNS 固定用 port 53
Name: google.com ← 你查的網域
Address: 142.250.185.14 ← 對應的 IP 位址
Code language: CSS (css)有趣的事實
DNS 查詢用的是 UDP(不是 TCP),因為查詢內容很小,速度比可靠性重要。如果 UDP 封包掉了,瀏覽器就再發一次查詢就好。
Vibe Coder 檢查點
當你部署應用或設定網域時:
- [ ] DNS 設定有沒有正確指向你的伺服器 IP?
- [ ] DNS 快取的 TTL(Time To Live)是多少?改了 DNS 記錄後可能要等快取過期才生效
- [ ] 用
nslookup或dig驗證 DNS 是否解析正確
整篇重點回顧
必看懂(核心概念):
CAP 定理 → 分散式系統只能三選二,真實世界通常是 CP 或 AP
延遲 → 一個請求多久完成(看 P95、P99)
吞吐量 → 每秒能處理多少請求(看 RPS)
TCP → 可靠但慢,用於網頁和 API(看到 SOCK_STREAM)
UDP → 快但不保證,用於串流和遊戲(看到 SOCK_DGRAM)
DNS → 把網址翻譯成 IP 位址
知道就好(遇到再查):
SLI/SLO/SLA → 效能承諾的三個層級
IPv4 vs IPv6 → 舊版地址快用完,新版很長但數量幾乎無限
IP 標頭 → 每個網路封包前面的「信封」資訊
DNS 記錄類型 → A、AAAA、CNAME、MX 等不同用途的記錄
下一篇預告
下一篇我們會進入應用層協定 — HTTP、REST API、WebSocket,這些是你每天都在用(但不一定理解)的東西。當你用 AI 寫一個 API,它回傳的 200、404、500 到底是什麼意思?我們下篇見。
進階測驗:設計需求與網路基礎 — CAP 定理、延遲與通訊協定
共 5 題,包含情境題與錯誤診斷題。