前言
無論是 LINE、WeChat 還是 WhatsApp,即時通訊早已是每天不可或缺的工具。
但要讓數億使用者在不到一秒內完成收發訊息,背後牽涉到連線管理、跨機器轉發、離線儲存與故障恢復等一整套分散式設計。
本篇文章以「一億活躍用戶」量級為背景,透過五維度分析法,拆解大型 Chat Service 的核心技術與架構取捨。
這篇你可以帶走什麼
- 即時通訊系統在功能邊界與流量上的核心壓力點
- 為什麼 WebSocket 是主流解,但行動網路下仍有邊界
- 聊天伺服器常見架構盲點(Session Affinity)與可擴展替代解
- 離線訊息儲存與連線容量規劃的實務思路
維度一、可直接觀察的事實:系統邊界與流量特徵
先把需求邊界定清楚。
核心功能通常包含:
- 一對一聊天
- 群組聊天(通常限制 200 到 500 人,避免運算爆炸)
- 上線狀態顯示(在線 / 離線)
- 離線訊息暫存與補發
一個關鍵物理限制是:傳統 HTTP 模型下,伺服器無法穩定地主動推送訊息到手機客戶端。
再看流量規模估算。假設:
- 10 億註冊用戶
- 2 億日活躍用戶 (DAU)
- 尖峰同時在線約 5000 萬
- 每秒產生約 1000 萬筆訊息
- 每筆訊息大小約 0.5KB
則尖峰傳輸量約:
- 1000 萬 x 0.5KB = 每秒 5GB 傳輸頻寬
這個量級決定了系統必須優先解決「長連線效率」與「跨節點轉發成本」。
重點:即時通訊瓶頸通常不是資料庫寫不進去,而是如何穩定維持海量長連線並快速把訊息送到正確節點。
維度二、條件檢查:通訊協定的最佳解與邊界
一般情況下的最佳解(WebSocket)
為了突破 HTTP 單向限制,主流做法是使用 WebSocket,它允許客戶端與伺服器建立一條持久的雙向通訊管道 (Persistent Connection),不僅延遲極低,傳輸的標頭 (Header) 開銷也遠小於傳統的 HTTP 輪詢 (Polling) 或長輪詢 (Long-polling)。
這讓訊息收發體感更接近「即時」。
邊界條件(行動網路不穩定)
在手機端,使用者可能進電梯、跨基地台、從 5G 切到 Wi-Fi,造成 IP 改變與網路頻繁斷線。
此時純粹依賴 TCP 建立的 WebSocket 必須不斷經歷耗時的「重新握手建線 (Handshake)」過程,對穩定性與延遲都不友善。
針對這種極端邊界,可以考慮採用 Google 提出的 QUIC 協定(基於 UDP),它允許使用者在切換網路時無縫恢復連線,無需重新建立連線。
重點:WebSocket 是主流解,但在行動網路場景需要搭配重連與傳輸層優化策略。
維度三、反證檢查:跳脫直覺的伺服器架構盲點
盲點一:把聊天雙方綁在同一台伺服器(Session Affinity)
直覺上,若 A 與 B 都在同台伺服器,訊息可在記憶體內直送,延遲最低。
但在億級用戶系統中,每個人同時參與多個群組與私聊,幾乎不可能穩定讓所有相關對話都落在同機。
結果會出現:
- 熱點節點(Hotspot)
- 頻繁搬遷連線(Thrashing)
盲點二:各自連線 + 全域狀態查表 + 跨機轉發(可擴展解)
更穩健做法是:
- A、B 各自連最近的聊天伺服器
- 透過全域 Session Register(KV Store)查 B 目前在哪台伺服器
- 使用 Pub/Sub 或 Message Queue 跨伺服器轉發
- 由 B 所在伺服器推送給 B
這種設計雖然多了一跳,但可擴展性與穩定性更好。
維度四、不確定性分析:伺服器極限與離線處理
先區分事實與推論。
- 觀察事實:單台普通的伺服器大約只能同時扛住 50,000 個連線(受限於 OS 的 File Descriptor 與記憶體限制)
- 對應估算:若 5000 萬同時在線,理論上至少需約 1000 台伺服器
但工程上也有優化空間:
- 經驗推論 (C10M Challenge):如果透過內核優化、epoll/kqueue 等非同步 I/O 模型(如 WhatsApp 早期著名的架構),理論上單機可以撐到 200 萬甚至 1000 萬個並發連線。這會大幅減少伺服器數量至數十台,進而大幅降低伺服器之間轉發訊息的開銷。
另一個核心假設是:多數訊息發送時對方在線。
對離線用戶,系統必須將訊息存入「離線儲存層 (Offline Storage)」:
- 可用 NoSQL(如 Cassandra)或單純的 File System 實作儲存待送訊息
- 用戶上線後由伺服器將這些離線訊息拉出並推播
- 補發成功後刪除離線副本以節省空間並降低隱私風險
維度五、最終結論與行動建議
架構藍圖可拆成四層:
- 連線層:客戶端透過 WebSocket(或 QUIC)連到 Stateless Chat Server
- 狀態追蹤層:用 KV Store(如 Redis)維護 Session Register,隨時記錄哪個 User ID 目前綁定在哪一台伺服器上,並透過心跳訊號 (Heartbeat) 定期更新
- 轉發層:用 Pub/Sub 或 MQ 處理跨伺服器訊息傳遞
- 儲存層:獨立 Offline Storage 管理離線訊息
破關路線圖(信心度 95%)
- 先把連線層做成 Stateless,避免 Session 黏著導致擴展受限
- 建立 Session Register,讓訊息路由可被全域查詢
- 以 Pub/Sub 打通跨伺服器轉發,確保訊息能送到正確節點
- 對離線用戶建立補發流程與刪除策略,平衡體驗、成本與隱私
這套設計高度契合現代分散式即時通訊系統的標準做法。
脆弱點提示
如果這個系統是一套「企業內部合規與稽核專用」的通訊軟體(如 Slack 的某些方案),那麼上述「訊息送達後即可刪除」的輕量化假設就會完全出錯。因為企業通訊需要「無限期儲存所有歷史紀錄並支援全文檢索」,這會強制系統引入龐大的長期資料庫與 ElasticSearch 叢集,讓整體架構的儲存與同步成本呈現指數級暴增。
一句話總結
即時通訊系統的關鍵不只在 WebSocket,而在於連線管理、跨節點路由與離線補發三者的協同設計,才能在億級規模下維持低延遲與高可用。