iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
Software Development

30 天從 Full-Stack Engineer 進化到 System Design:從 0 設計可支撐百萬使用者的系統系列 第 22 篇

# Day 22|Design Chat System:WhatsApp / Messenger 的即時訊息到底怎麼設計?

  • 分享至 

  • xImage
  •  

Day 21 我們設計了 Notification System。Day 22 來設計另一個經典 System
Design:

Chat System(聊天系統 / 即時訊息系統)

今天的規則仍然一樣:

每個新名詞都先解釋完整英文、中文意思、它是什麼、為什麼需要、簡單例子,再放進
Architecture。


1. Chat System 是什麼?

Chat System(聊天系統 / 即時訊息系統):

讓 Users 可以透過 Network 傳送與接收 Messages 的 System。

最簡單:

Alvin
↓
"Hello"
↓
Server
↓
Bob

大型 Chat System 還需要:

One-to-One Chat
Group Chat
Message History
Online / Offline
Delivered Status
Read Status
Multiple Devices
Offline Messages
Message Ordering
Reconnect

2. One-to-One Chat

One-to-One Chat(一對一聊天):

兩個 Users 之間的 Conversation。

Alvin ↔ Bob

3. Group Chat

Group Chat(群組聊天):

多個 Users 共同參與同一個 Conversation。

例如:

Group: CSYE6200
Members: Alvin, Bob, Charlie, David

Alvin 發一則 Message,其他 Members 都可能需要收到。

這會產生:

一個 Message
↓
很多 Recipients

後面會介紹 Fan-out(扇出 / 一對多擴散)。


4. Conversation

Conversation(對話 / 會話):

一組 Users 之間持續交換 Messages 的邏輯空間。

conversation_id = C123

Members:
Alvin
Bob

Messages:
M1 → Hello
M2 → Hi
M3 → How are you?

5. Message ID

ID = Identifier

Identifier → 識別碼

Message ID(訊息識別碼):

唯一識別某一則 Message 的值。

M1001 → Hello
M1002 → Hello

雖然 Content 一樣,但 Message ID 不同,所以 System 知道它們是不同
Messages。

Message ID 可以協助:

Deduplication
Ordering
Delivery Tracking
Read Receipt

6. Real-Time Communication

Real-Time Communication(即時通訊):

Real-Time → 即時 / 非常接近事件發生的時間
Communication → 通訊

意思:

Message 發生後,希望 Recipient 在很短時間內收到。

Alvin sends → 10:00:00.000
Bob receives → 10:00:00.150

大約 150 ms。

Real-Time 不代表一定是 0 ms,而是 Latency 足夠低,讓 User
感覺互動接近即時。


7. Latency

Latency(延遲):

一個 Operation 從開始到得到結果所花的時間。

Chat:

Alvin Send
↓
Server
↓
Bob Receive

如果 100 ms,User 通常感覺很快;如果 10 seconds,Chat Experience
就很差。


8. HTTP

HTTP = Hypertext Transfer Protocol

Hypertext → 超文字
Transfer → 傳輸
Protocol → 協定

中文:

超文字傳輸協定

Protocol(協定):

兩個 Systems 溝通時共同遵守的一組規則。

一般 HTTP 常見:

Client
↓
Request
↓
Server
↓
Response
↓
Client

9. Client 與 Server

Client(客戶端):

主動使用 Server 提供服務的 Software / Device。

例如:

Browser
iPhone App
Android App
Desktop App

Server(伺服器):

接收 Client Requests、處理工作並提供服務的 Computer / Software。


10. Polling

Bob 想知道 Alvin 有沒有新 Message,最簡單可以一直問:

GET /messages
↓
Nothing

2 seconds later
↓
GET /messages
↓
Nothing

這叫:

Polling(輪詢)

Client 固定一段時間向 Server 詢問:「有沒有新的資料?」

問題:

很多 Requests
↓
其實沒有新 Message

可能浪費 Network、Server CPU 與其他 Resources。


11. Long Polling

Long Polling(長輪詢):

Client 發 Request 後,如果沒有新資料,Server
不立即回覆,而是先等待一段時間。

Bob
↓
GET /messages
↓
Server waits...
↓
Alvin sends "Hello"
↓
Server returns "Hello"

如果一直沒資料,最後 Timeout,Client 再建立新的 Request。

它比普通 Polling 減少無意義 Requests,但仍是:

Request → Wait → Response → New Request

12. WebSocket

WebSocket 是一種 Network Communication Protocol。

可以先理解成:

Client 和 Server 建立一條可以長時間保持,而且雙方都能主動傳送 Data 的
Connection。

Bob
↕
WebSocket
↕
Chat Server

建立後,Server 有新 Message 時可以直接透過 Connection 傳給 Bob,不需要
Bob 每兩秒問一次。


13. Connection

Connection(連線):

兩個 Network Endpoints 之間建立的通訊關係。

例如:

Bob's Phone
↕
Chat Server

14. Persistent Connection

Persistent = 持續存在的

Persistent Connection(持久連線 / 長連線):

Connection 建立後不會在一次 Message 完成後立刻關閉,而是維持較長時間。

Connect
↓
Keep Connection Open
↓
Message
↓
Message
↓
Message

這很適合 Chat。


15. Bidirectional Communication

Bidirectional Communication(雙向通訊)

Bi → Two / 兩個
Directional → 方向
Communication → 通訊

意思:

Client 和 Server 都可以主動傳送 Data。

Client → Server
Server → Client

16. Full-Duplex

Full-Duplex Communication(全雙工通訊):

雙方可以同時向彼此傳送 Data。

可以想成電話:

Alvin ↔ Bob

雙方都可以說話與接收。

初學階段先記:

WebSocket
→ Persistent Connection
→ Bidirectional Communication
→ 適合 Real-Time Chat

17. WebSocket vs Polling

方法 概念 Server 可主動傳資料? Connection


Polling Client 一直問 不直接 多次 Request
Long Polling Server 等到有資料才回 間接 Request 結束後重建
WebSocket 保持雙向連線 可以 Persistent

Chat 的 Real-Time Delivery 很適合 WebSocket。

但 Login、Load History、Create Group 等功能仍然可以使用普通 HTTP API。


18. Chat Architecture v1

Alvin Client
     ↕
  WebSocket
     ↕
 Chat Server
     ↕
  WebSocket
     ↕
 Bob Client

流程:

Alvin sends "Hello"
↓
Chat Server receives
↓
Find Bob's connection
↓
Send to Bob

19. Connection Server

Users 變成 Millions 時,一台 Server 不可能管理全部 Connections。

Connection Server(連線伺服器):

專門維護大量 Client Connections,接收與傳送 Real-Time Messages 的
Server。

Alvin → Connection Server A
Bob → Connection Server B

20. Concurrent Connections

Concurrent = 並發的 / 同時存在的

Concurrent Connections(並發連線):

同一時間保持中的 Connections 數量。

例如:

10M Users Online
≈ 10M Concurrent Connections

這和:

10M Requests/day

不是同一件事。


21. Horizontal Scaling

Horizontal Scaling(水平擴展):

增加更多 Servers / Machines 共同處理 Traffic。

Connection Server #1
Connection Server #2
Connection Server #3
...

如果一台安全處理 100K Connections,而 Peak 有 10M
Connections,就需要多台 Servers。


22. Connection Mapping

新問題:

Alvin → Server A
Bob → Server B

Server A 怎麼知道 Bob 在 Server B?

需要:

Connection Mapping(連線對應)

記錄 User / Device 現在連在哪一台 Connection Server。

Alvin → Server A
Bob → Server B
Carol → Server C

23. Connection Registry

Registry = 登錄表 / 註冊資訊

Connection Registry(連線登錄資訊):

保存 User / Device 與 Connection Server 對應關係的資料。

User 123
→ Device A
→ Server B
→ Connection XYZ

24. Routing

Routing(路由 / 分流):

決定 Data 應該送到哪個 Destination。

recipient = Bob
↓
Lookup Registry
↓
Bob → Server B
↓
Route to Server B

可以有 Message Router(訊息路由器) 負責這件事。


25. Online / Offline

Online(在線):

User / Device 目前有可用 Connection,或近期仍被視為 Active。

Offline(離線):

User / Device 目前沒有可用的 Real-Time Connection。

但 Online Status 不一定瞬間完全準確,因為 Network 可能突然消失,而
Server 需要時間才能發現。


26. Presence

Presence(在線狀態 / 活躍狀態):

描述 User 現在是否 Online、Offline、Away 等。

Alvin → ONLINE
Bob → OFFLINE
Carol → AWAY

可以建立:

Presence Service(在線狀態服務)

負責管理這些狀態。


27. Heartbeat

Server 怎麼知道 Client Connection 還活著?

Heartbeat(心跳訊號):

Client / Server 定期傳送小型 Signal,表示 Connection / Process
仍然正常。

像人的心跳:

持續有心跳
→ 還活著

System:

Client → PING
Server → PONG

28. Ping / Pong

Ping:

用來確認對方是否仍然可連線的小型訊號。

Pong:

對 Ping 的回覆。

PING → Are you alive?
PONG → Yes.

如果很久沒有收到 Pong,Server 可以判斷 Connection 可能已經失效。


29. Offline Message

Offline Message(離線訊息):

Recipient Offline 時仍被 System 保存,等 User 重新連線後再傳送的
Message。

10:00 Alvin → Hello
Bob Offline
↓
Message stored

10:30 Bob reconnects
↓
Deliver "Hello"

30. Persistent Storage

Persistent Storage(持久化儲存):

Process / Machine Restart 後,Data 仍可以保留下來的 Storage。

Chat Messages 通常不能只放 RAM:

Server Crash
↓
RAM Data lost

因此需要 Database / Durable Storage 保存 Message History。


31. Message Storage

Message Storage(訊息儲存層):

專門保存 Chat Messages 的 Database / Storage。

例如:

message_id
conversation_id
sender_id
content
created_at
sequence_number

32. Message History

Message History(聊天紀錄):

Conversation 過去保存的 Messages。

User 打開 Chat:

Load latest 50 messages

可以透過 HTTP API:

GET /conversations/C123/messages

33. Pagination

如果 Conversation 有 1M Messages,不能一次全部傳回。

Pagination(分頁):

把大量 Data 分成小批、小頁讀取。

Latest 50
Previous 50
Previous 50
...

34. Cursor

Cursor(游標):

用一個位置標記,告訴 Server 下一次應從哪裡繼續讀。

例如:

GET /messages?before=M1000&limit=50

意思:

給我 M1000 之前的 50 則 Messages

35. Message Ordering

Message Ordering(訊息順序):

確保 Messages 以合理的先後順序呈現。

Alvin:

M1: Hello
M2: How are you?

Bob 不希望看到:

How are you?
Hello

36. 為什麼會亂序?

Distributed System 中可能:

M1 → Server A → slow
M2 → Server B → fast

結果:

M2 arrives first
M1 arrives later

所以 Arrival Order 不一定等於 Sender 原本的 Order。


37. Timestamp

Timestamp(時間戳記):

記錄某件事情發生的時間。

M1 → 10:00:00.100
M2 → 10:00:00.200

看起來可以排序,但不同 Machines 的 Clocks 不一定完全一致。


38. Clock Skew

Clock = 時鐘

Skew = 偏差

Clock Skew(時鐘偏差):

不同 Machines 的 Clock 顯示時間存在差異。

所以不能盲目假設所有 Servers 的 Timestamp 都能提供完美 Global Ordering。


39. Sequence Number

Sequence Number(序號 / 順序號):

用遞增 Number 表示 Message 在某個 Conversation 裡的順序。

C123:

M1 → sequence 101
M2 → sequence 102
M3 → sequence 103

即使 M2 比 M1 更早到 Client,也可以按照 Sequence Number 排成:

101 → 102 → 103

40. Global Ordering vs Per-Conversation Ordering

Global Ordering(全域順序):

整個 System 所有 Messages 都有唯一完整的先後順序。

這通常很昂貴,而且 Chat 不一定需要。

Per-Conversation Ordering(每個 Conversation 內的順序):

只要求同一個 Conversation 裡的 Messages 有合理順序。

Conversation A:
1 → 2 → 3

Conversation B:
1 → 2 → 3

A 和 B 誰先通常不重要。


41. Message Status

常見:

SENDING
SENT
DELIVERED
READ

SENDING

Client 正嘗試傳給 Server,Server 還沒確認。

SENT

可以定義成 Server 已成功接受並保存 Message。

DELIVERED

Message 已到達 Recipient Device / Client。

READ

Recipient 已查看 Message。

實際 Product 可以有不同定義,因此 Interview 中要先說清楚 Status
Semantics。


42. ACK

ACK = Acknowledgement

Acknowledgement → 確認 / 確認收到

意思:

接收方告訴發送方:「我已收到 / 處理這筆資料。」

Client
↓
M1001
↓
Server

Server
↓
ACK M1001
↓
Client

43. Delivery ACK

Delivery ACK(送達確認):

Recipient Device 告訴 Server:Message 已經到達。

Server → Bob Device → M1001
Bob Device → Server → ACK M1001

Server:

M1001 → DELIVERED

44. Read Receipt

Receipt = 回執 / 確認紀錄

Read Receipt(已讀回執):

Recipient 告訴 System 某個 Message 已經被閱讀。

Bob reads M1001
↓
READ_RECEIPT
↓
Server
↓
Alvin sees "Read"

因此:

SENT ≠ DELIVERED ≠ READ

45. Client Message ID

Network Failure 時:

Client sends Hello
↓
Server receives it
↓
Response lost

Client 不知道 Server 到底有沒有收到,因此 Retry,可能產生兩則 Hello。

可以讓 Client 先建立:

Client Message ID(客戶端訊息識別碼)

client_message_id = ABC123

Retry 時仍使用:

ABC123

Server 就知道:

same logical message

46. Idempotency

Idempotency(冪等性):

同一個 Operation 重複執行時,不應產生不必要的重複結果。

ABC123 → Hello
ABC123 → Hello
ABC123 → Hello

Server 最後只建立一個 Logical Message。


47. Deduplication

Deduplication(去重)

De- → 去除
Duplication → 重複

意思:

辨認並忽略重複的 Message / Request。

ABC123 already processed
↓
Do not create another message

48. Reconnect

Reconnect(重新連線):

Connection 中斷後,Client 再建立新的 Connection。

Mobile User 可能:

Wi-Fi
↓
Elevator
↓
No Signal
↓
5G

WebSocket 很容易因 Network Change 中斷。


49. Synchronization

Reconnect 期間可能漏掉 Messages。

Synchronization(同步 / 狀態同步):

讓 Client 補回缺少的 Data,最後恢復到最新正確狀態。

例如:

Client last sequence = 100
Server latest = 105

Server 補:

101
102
103
104
105

50. Sync

Sync = Synchronization

中文:

同步

Chat Context 裡的 Message Sync:

把缺少或更新的 Messages 同步到 Client。


51. Recovery

Recovery(恢復):

Failure 發生後,讓 System / Client 回到正確可用狀態。

Connection Failure
↓
Reconnect
↓
Sync missing messages
↓
Recovery

52. Multi-Device

Multi-Device(多裝置):

同一個 User 在多個 Devices 使用同一 Account。

Alvin
├── iPhone
├── Mac
└── Browser

所以:

1 User ≠ 1 Connection

53. Device ID

Device ID = Device Identifier

Device → 裝置
Identifier → 識別碼

中文:

裝置識別碼

可以用來區分 User 的不同 Devices。


54. Multi-Device Synchronization

Alvin 在 iPhone 傳:

Hello Bob

Alvin 的 Mac 也應該看到這則 Message。

所以除了 Recipient Delivery,還可能需要:

Multi-Device Synchronization(多裝置同步)


55. Fan-out

Group 有 1,000 Members:

Alvin sends 1 message
↓
999 recipients

這叫:

Fan-out(扇出 / 一對多擴散)

一個 Message / Event 產生多個 Delivery Tasks。


56. Fan-out on Write

Fan-out on Write(寫入時扇出):

Fan-out → 一份資料擴散成多份 Delivery Work
on Write → 寫入時就執行
1 Group Message
↓
Create delivery work for many recipients

優點:

Recipient delivery can be fast

缺點:

Large Group
→ Lots of write work

57. Write Amplification

Write Amplification(寫入放大):

一個 Logical Write 最後造成多次實際 Writes / Work。

1 Group Message
↓
999 Delivery Records

就是 Write Amplification 的例子。


58. Fan-out on Read

Fan-out on Read(讀取時扇出 / 讀取時組合):

寫入時先保存較少資料,User Read 時再找出自己應該看到的 Messages。

Write:
Store group message

Read:
User opens group
↓
Query relevant messages

Trade-off:

Less write amplification
but
Read path may be more expensive

59. Trade-off

Trade-off(取捨):

得到某個好處時,通常需要付出另一種 Cost。

所以不是:

Fan-out on Write 永遠最好

或:

Fan-out on Read 永遠最好

要看:

Group Size
Message Frequency
Latency Requirement
Read Pattern
Storage Cost

60. Partitioning

Messages 成長到 Billions:

Partitioning(分區):

把大型 Dataset 分成多個較小部分。

例如:

Conversation A → Partition 1
Conversation B → Partition 2
Conversation C → Partition 3

61. Partition Key

Partition Key(分區鍵):

用來決定某筆 Data 應放在哪個 Partition 的 Key。

Chat 可以考慮:

conversation_id

因為同一 Conversation 的 Messages 常一起被查詢。


62. Sharding

Sharding(資料分片):

把 Dataset 水平切開,並分散到多個 Database Servers。

簡單記:

Replication
→ Copy Data

Sharding
→ Split Data

63. Hot Partition

如果一個超熱門 Group 每秒有大量 Messages,而且全部落在同一 Partition:

Hot Partition(熱分區):

某個 Partition 承受遠高於其他 Partitions 的 Traffic / Load。

這是一種 Hotspot(熱點):

Work 過度集中在某個 Component / Data Range。


64. Message Queue

Chat System 也可能使用:

Message Queue(訊息佇列)

Message → 訊息
Queue → 排隊隊伍 / 佇列

用途可能包括:

Decoupling
Traffic Buffering
Asynchronous Delivery
Retry
Fan-out

但不要因為是大型 System 就無腦加入 Queue。

先問:

Queue 解決什麼 Problem?

65. Offline Push Notification

Bob Offline:

No WebSocket

Chat System 可以:

Persist Message
↓
Notification System
↓
Push Notification
↓
Bob Phone

例如:

Alvin sent you a message.

66. APNs

APNs = Apple Push Notification service

Apple → Apple
Push Notification → 推播通知
service → 服務

中文:

Apple 推播通知服務

用來把 Push Notification 傳到 Apple Devices。


67. FCM

FCM = Firebase Cloud Messaging

Firebase → Google 的 App Development Platform 名稱
Cloud → 雲端
Messaging → 訊息傳遞

中文可理解為:

Firebase 雲端訊息服務

常用於 Mobile Push Messaging。


68. Authentication

Authentication(身分驗證):

確認「你是誰」。

例如:

Login
↓
Access Token
↓
Open WebSocket
↓
Server verifies identity

69. Authorization

Authorization(授權):

確認「你有沒有權限做這件事情」。

Authentication:
你是不是 Alvin?

Authorization:
Alvin 能不能讀 Conversation C123?

即使 Alvin 已經 Login,也不能讀自己沒有加入的 Private Group。


70. WSS

Messages 在 Network 中傳輸時需要保護。

WSS = WebSocket Secure

WebSocket → WebSocket 通訊
Secure → 安全的

中文可以理解成:

安全的 WebSocket Connection

通常代表:

WebSocket over TLS

71. TLS

TLS = Transport Layer Security

Transport Layer → 傳輸層
Security → 安全

中文:

傳輸層安全協定

TLS 主要協助提供:

Encryption
Integrity
Server Authentication

72. Transport Layer

Transport Layer(傳輸層):

Network Communication 中,負責 Application 之間 End-to-End Data
Transport 的 Layer。

常見 Protocol:

TCP
UDP

今天不需要背完整 OSI Model。

先知道:

Application Data
↓
Network Layers
↓
另一台 Machine

而 TLS 用來保護傳輸中的 Communication。


73. E2EE

Chat App 常看到:

E2EE = End-to-End Encryption

End-to-End → 從通訊的一端到另一端
Encryption → 加密

中文:

端到端加密

核心概念:

Message 在 Sender 端加密,只有預期的 Recipient Endpoint 能解密;中間
Server 不應取得可直接閱讀的 Message Plaintext。

Alvin
↓
Encrypt
↓
Ciphertext
↓
Server
↓
Ciphertext
↓
Bob
↓
Decrypt

74. Plaintext / Ciphertext

Plaintext(明文):

尚未被 Encryption 保護、可以直接閱讀的原始內容。

Hello Bob

Ciphertext(密文):

Encryption 後產生、沒有正確 Key 時不應直接可讀的 Data。

Plaintext
↓
Encryption
↓
Ciphertext

75. TLS vs E2EE

TLS / WSS

主要保護:

Client ↔ Server

之間的 Network Transport。

E2EE

目標:

Sender
↓
Encrypted
↓
Server
↓
Encrypted
↓
Recipient

Server 不應直接閱讀 Message Content。

因此:

TLS ≠ E2EE

E2EE 還涉及 Key Management、Multi-Device、New Device、Group Membership
等更複雜問題,今天先理解目的即可。


76. Reliability

Reliability(可靠性):

即使部分 Components Failure,System 仍能盡可能正確提供服務並恢復。

Connection Server Crash:

Client disconnects
↓
Reconnect
↓
Another Server
↓
Sync missing messages

77. Failover

Failover(故障切換):

原本 Component Failure 時,切換到其他可用 Component。

Server A ❌
↓
Reconnect
↓
Server B ✅

78. Retry

Retry(重試):

Operation 失敗後,再嘗試一次。

但 Retry Message 可能造成 Duplicate,所以要搭配:

Client Message ID
Idempotency
Deduplication

79. Exponential Backoff

如果 10M Clients 同時斷線,不能不停立即 Reconnect。

Exponential Backoff(指數退避):

每次失敗後逐漸增加 Retry 等待時間。

1 sec
2 sec
4 sec
8 sec

80. Jitter

Jitter(隨機抖動 / 隨機延遲):

在 Retry Delay 中加入 Randomness。

Client A → 3.8 sec
Client B → 4.2 sec
Client C → 4.7 sec

避免全部 Clients 同時重連。


81. Thundering Herd

Thundering Herd(驚群效應):

大量 Clients / Workers 同時對同一 Resource 發 Request,瞬間造成巨大
Load。

例如:

Chat Server outage
↓
10M clients disconnect
↓
Server recovers
↓
10M clients reconnect together

所以常搭配:

Exponential Backoff
+
Jitter

82. Observability

Observability(可觀測性):

透過 Metrics、Logs、Traces 等 Signals 理解 System 內部發生什麼。

Chat 可以監控:

Active Connections
Connection Success Rate
Reconnect Rate
Messages/sec
Delivery Latency
Failure Rate
Queue Backlog
Database Latency
p95 / p99 Latency

83. RPS

RPS = Requests Per Second

Requests → 請求
Per Second → 每秒

中文:

每秒 Request 數量

但 Chat 不能只看 RPS。

還需要:

Concurrent Connections
Messages/sec

84. DAU

DAU = Daily Active Users

Daily → 每日
Active → 活躍
Users → 使用者

中文:

每日活躍使用者

假設:

50M DAU
40 messages/user/day

每天:

50M × 40
= 2B Messages/day

一天約 100K seconds:

2B / 100K
≈ 20K Messages/sec average

如果 Peak 是 5 倍:

≈ 100K Messages/sec

85. Concurrent Connection Estimation

假設 Peak:

10M Users Online

平均:

1.5 active device connections/user

那麼:

10M × 1.5
= 15M Concurrent Connections

這告訴我們 Connection Layer 必須 Horizontal Scale。


86. Storage Estimation

假設:

2B Messages/day
500 Bytes/message

Raw Data:

≈ 1 TB/day

一年:

≈ 365 TB

還沒有算:

Indexes
Replication
Metadata
Attachments
Backups

87. Metadata

Metadata(中繼資料 / 描述資料的資料):

不是 Message Content 本身,而是描述 Message 的資訊。

例如:

message_id
sender_id
conversation_id
created_at
sequence_number
status

88. Attachment

Attachment(附件):

附加在 Message 裡的 File。

例如:

Image
Video
PDF
Audio

大型 File 通常不直接放進普通 Message Database Row,而可以放進:

Object Storage

89. Object Storage

Object Storage(物件儲存):

適合保存 Images、Videos、Documents 等大型 Files / Objects 的 Storage
System。

Message Database
→ Metadata + file reference

Object Storage
→ Actual image/video

90. CDN

CDN = Content Delivery Network

Content → 內容
Delivery → 傳遞
Network → 網路

中文:

內容傳遞網路

用途:

把 Content 放到靠近 User 的 Edge,降低 Network Distance 與 Origin
Load。

Chat Images / Videos 可以:

Object Storage
↓
CDN
↓
User

91. Full Chat Architecture

                    ┌──────────────────────┐
                    │      HTTP APIs       │
                    │ Login / History etc. │
                    └──────────┬───────────┘
                               │
                               ↓
Alvin Client              API Services
     │
     │ WSS
     ↓
Connection Server A
     │
     ↓
Message Service
     │
     ├────────→ Message Storage
     │
     ├────────→ Message Queue
     │
     ↓
Message Router
     │
     ├────────→ Connection Registry
     │
     ↓
Connection Server B
     │
     │ WSS
     ↓
Bob Client

If Bob Offline:

Message Service
     ↓
Message Storage
     ↓
Notification System
     ↓
APNs / FCM
     ↓
Bob Device

Supporting Services:

Presence Service
Synchronization Service
Group / Membership Service
Observability

92. Send Message Flow

Alvin 傳:

Hello Bob

可以經過:

1. Client generates client_message_id
2. Send through WebSocket
3. Authenticate connection
4. Validate request
5. Authorize conversation access
6. Deduplicate client_message_id
7. Generate server message_id
8. Assign sequence_number
9. Persist Message
10. ACK Sender
11. Find Bob's connections
12. Route Message
13. Bob receives Message
14. Bob sends Delivery ACK
15. Update DELIVERED
16. Bob reads Message
17. Send Read Receipt
18. Update READ
19. Sync status to Alvin's other devices

93. Offline Flow

Alvin
↓
Message
↓
Persist
↓
Bob has no active connection
↓
Store as undelivered
↓
Notification System
↓
Push Notification

Bob 回來:

Reconnect
↓
Authenticate
↓
Send last received sequence
↓
Server finds missing messages
↓
Sync

94. Group Chat Flow

Alvin
↓
Connection Server
↓
Message Service
↓
Persist one logical message
↓
Group Membership
↓
Find recipients
↓
Fan-out
↓
Route to online members
↓
Store / Sync for offline members

Large Group 要注意:

Fan-out Cost
Write Amplification
Hot Partition
Queue Backlog
Connection Capacity

95. 每個 Component 為什麼存在?

WebSocket

Problem:
Chat needs low-latency bidirectional communication

Solution:
Persistent bidirectional connection

Connection Registry

Problem:
Bob may be connected to any server

Solution:
Track User / Device → Server mapping

Message Storage

Problem:
Offline users and history require persistence

Solution:
Persist messages

Sequence Number

Problem:
Distributed delivery may arrive out of order

Solution:
Per-conversation ordering

ACK

Problem:
Sender does not know whether receiver got data

Solution:
Acknowledgement

Client Message ID

Problem:
Retry may create duplicate messages

Solution:
Identify same logical message

Heartbeat

Problem:
Connection may die silently

Solution:
Periodic liveness signal

Reconnect + Sync

Problem:
Network interruption can cause missing messages

Solution:
Reconnect and recover missing data

Fan-out

Problem:
One group message has many recipients

Solution:
Expand one logical message into delivery work

96. 台積 IT 面試:為什麼 Chat 要用 WebSocket?

不要只說:

Because WebSocket is real-time.

可以回答:

Chat requires low-latency bidirectional communication. Polling
requires the client to repeatedly ask the server for new messages,
which creates unnecessary requests. WebSocket maintains a persistent
connection so both client and server can send data through the same
connection, making it suitable for real-time message delivery.


97. Bob Offline 怎麼辦?

1. Persist Message
2. Detect Bob has no active connection
3. Keep Message as undelivered
4. Optionally trigger Push Notification
5. Bob reconnects
6. Client reports last received sequence
7. Server synchronizes missing Messages
8. Update Delivery Status

98. 怎麼避免 Duplicate Message?

Client generates client_message_id
↓
Send
↓
Server stores ID
↓
Network failure
↓
Client retries same ID
↓
Server detects duplicate
↓
Return existing result

核心:

Idempotency
+
Deduplication

99. 怎麼處理 Message Ordering?

不要只回答:

Use Timestamp

先問:

Global Ordering?
Per-Conversation Ordering?

Chat 通常更需要:

Per-Conversation Ordering

可以考慮:

conversation_id
+
sequence_number

Timestamp 可以當 Metadata,但不同 Machines 可能有 Clock Skew。


100. 怎麼知道 User Online?

可以結合:

WebSocket Connection
+
Connection Registry
+
Heartbeat
+
Presence Service

但 Presence 不一定瞬間完美準確。

例如:

Bob suddenly loses network

Server 可能等 Heartbeat Timeout 後才知道。


101. Connection Server 掛掉怎麼辦?

Connection Server A crashes
↓
WebSocket disconnects
↓
Clients detect failure
↓
Exponential Backoff + Jitter
↓
Reconnect to Server B
↓
Update Connection Registry
↓
Sync missing messages

102. Multi-Device 怎麼辦?

不能假設:

user_id → one connection

而要考慮:

user_id
├── device A
├── device B
└── device C

Message 可能要送給 Recipient 的多個 Active Devices,也要同步到 Sender
自己的其他 Devices。


103. SQL vs NoSQL?

不要背:

Chat = NoSQL

先分析:

Access Pattern
Data Volume
Write Throughput
Ordering Requirement
Consistency Requirement
Query Pattern
Operational Complexity

例如常見 Query:

Give me latest 50 messages
for conversation C123
before sequence 1000

再根據 Requirement 選擇 Storage。


104. Day 22 Interview Checklist

□ One-to-One Chat
□ Group Chat
□ Conversation
□ Message ID
□ Real-Time Communication
□ Latency
□ HTTP
□ Polling
□ Long Polling
□ WebSocket
□ Persistent Connection
□ Bidirectional Communication
□ Full-Duplex
□ Connection Server
□ Concurrent Connections
□ Horizontal Scaling
□ Connection Mapping
□ Connection Registry
□ Routing
□ Presence
□ Heartbeat
□ Ping / Pong
□ Offline Message
□ Persistent Storage
□ Message History
□ Pagination
□ Cursor
□ Message Ordering
□ Timestamp
□ Clock Skew
□ Sequence Number
□ Per-Conversation Ordering
□ Sending / Sent / Delivered / Read
□ ACK
□ Delivery ACK
□ Read Receipt
□ Client Message ID
□ Idempotency
□ Deduplication
□ Reconnect
□ Synchronization
□ Multi-Device
□ Device ID
□ Fan-out
□ Fan-out on Write
□ Fan-out on Read
□ Write Amplification
□ Partitioning
□ Partition Key
□ Sharding
□ Hot Partition
□ Message Queue
□ APNs
□ FCM
□ Authentication
□ Authorization
□ WSS
□ TLS
□ Transport Layer
□ E2EE
□ Plaintext
□ Ciphertext
□ Reliability
□ Failover
□ Retry
□ Exponential Backoff
□ Jitter
□ Thundering Herd
□ Observability
□ RPS
□ DAU
□ Metadata
□ Attachment
□ Object Storage
□ CDN

105. 縮寫總整理

ID
= Identifier
= 識別碼

HTTP
= Hypertext Transfer Protocol
= 超文字傳輸協定

ACK
= Acknowledgement
= 確認 / 確認收到

WSS
= WebSocket Secure
= 安全的 WebSocket Connection

TLS
= Transport Layer Security
= 傳輸層安全協定

E2EE
= End-to-End Encryption
= 端到端加密

RPS
= Requests Per Second
= 每秒 Request 數量

DAU
= Daily Active Users
= 每日活躍使用者

APNs
= Apple Push Notification service
= Apple 推播通知服務

FCM
= Firebase Cloud Messaging
= Firebase 雲端訊息服務

CDN
= Content Delivery Network
= 內容傳遞網路

今天學到了什麼?

Chat System 看起來只是:

Alvin
↓
Hello
↓
Bob

真正設計時卻需要處理:

Real-Time Communication
WebSocket
Persistent Connections
Connection Routing
Presence
Heartbeat
Offline Messages
Message Storage
Ordering
Sequence Number
ACK
Delivered / Read Receipt
Idempotency
Deduplication
Reconnect
Synchronization
Multi-Device
Group Fan-out
Partitioning
Reliability
Security
Observability

每個 Component 都應該從 Problem 推導:

Polling 太浪費
↓
WebSocket

User 可能連不同 Server
↓
Connection Registry + Routing

User 可能 Offline
↓
Persistent Message Storage

Connection 可能靜默死亡
↓
Heartbeat

Network 可能中斷
↓
Reconnect + Sync

Retry 可能重複
↓
Client Message ID + Idempotency

Messages 可能亂序
↓
Per-Conversation Sequence Number

Group 有很多 Members
↓
Fan-out

Server 可能 Failure
↓
Reconnect + Failover

User 有多台 Devices
↓
Multi-Device Synchronization

核心仍然是:

Requirement
↓
Problem
↓
Bottleneck / Failure
↓
Solution
↓
Trade-off

好的 Chat System,不只是把 Message 從 Alvin 傳給 Bob,而是要在
Network Failure、Millions of Connections、Offline Users、Multiple
Devices、Group Fan-out 與 Out-of-Order Delivery 的情況下,仍然讓 User
感覺訊息快速、可靠,而且順序合理。


下一篇

Day 23|Design YouTube:Video
Upload、Storage、Transcoding、Streaming 與 CDN 到底怎麼設計?

會從最基礎解釋:

Video File
Upload
Object Storage
Metadata
Codec
Encoding
Decoding
Compression
Bitrate
Resolution
Container Format
Transcoding
Streaming
Buffer
Buffering
Chunk
Segment
Adaptive Bitrate Streaming
CDN
Origin
Edge Server
Cache
Upload Pipeline
Processing Pipeline
Thumbnail
Asynchronous Processing
Message Queue
Replication
Availability
Bandwidth
Egress

遇到縮寫,例如:

CDN
HLS
DASH
VOD

也會先按照:

完整英文
↓
每個字的意思
↓
中文意思
↓
為什麼需要
↓
簡單例子
↓
System Design 用法

再進入 Architecture。


上一篇
# Day 21|Design Notification System:Email、SMS、Push Notification 如何可靠地送到 Millions of Users?
下一篇
# Day 23|Design YouTube:Video Upload、Storage、Transcoding、Streaming 與 CDN 到底怎麼設計?
系列文
30 天從 Full-Stack Engineer 進化到 System Design:從 0 設計可支撐百萬使用者的系統 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言