後端系統設計 - 設計聊天系統 (Chat System)
2024年3月28日
本篇詳細解說本收錄在 E+ 的後端系統設計專題
在 前端系統設計 - 設計聊天系統 (Chat System) 我們從前端的角度來討論設計聊天系統,在這篇文章,我們將切換到後端的角度,來談設計聊天系統。
釐清需求
跟前端系統設計一樣,如果面試官問你,或者工作時 PM 跟你提說要設計聊天系統,第一個反應要是先去釐清需求。
除了在前端篇提到要釐清的
- 這個聊天系統的目標用戶是誰? 上面提的 Line、Instagram、Discord 目標族群很不同,都是聊天系統,但設計上會有差異
- 最基本的功能涵蓋什麼? 收發訊息外,需要有歷史記錄嗎? 要有聊天對象列表嗎?
- 收發的訊息類型是純文字的嗎? 還是要支援不同多媒體? 例如圖片、語音、影片等
- 聊天是即時的嗎? 還是非即時的聊天?
- 聊天都是 1 對 1 的嗎? 需要有群組聊天功能嗎?
一般從後端的角度還會要釐清
- 系統預計承載的規模? 訊息要存多久? (要去估算需要多少運算、存儲資源)
- 訊息種類的限制,例如文字的長度限制,或是有影音的話會如何限制?
- 需不需要處理端到端的訊息加密 (end-to-end encryption)?
- 要支援多裝置嗎? (例如同時支援網頁、行動端)
架構討論
跟前端篇一樣,先給定我們是處理 1 對 1 聊天,同時先以支援文字聊天為主,接著會再延伸討論其他會被追問的問題。當想到聊天系統,從最單純的角度來看,我們會有雙邊,一邊是發送訊息的人,另一邊是接收訊息的人,而在兩者中間則會是負責處理聊天的服務,服務同時會接到資料庫,來確保訊息都能被永久存下來。
這時會要面對我們必須做的第一個技術選擇,要讓收到訊息的人,能收到從伺服器端發來的訊息,該選什麼協定?
第一個是長輪詢 (long polling)
所謂的長輪詢,是讓客戶端發送請求,然後保持跟伺服器端的連接,直到伺服器端回應後,才會再發送新的請求。長輪詢跟輪詢 (polling) 的差別在於,一般的輪詢會是固定一段時間,客戶端持續發送請求,即使伺服器端沒有回應,仍然會持續發送,這會導致許多不必要的浪費。
而長輪詢因為會維持著連接,直到拿到回應才會再發送下個請求,相比起來會少掉許多不必要的浪費。但要注意,如果是長時間沒有發送訊息,因為連接會有 timeout
的狀況,因此仍會有斷掉後需要重新連線的浪費問題。
第二個是 Server-sent Event
Server-sent Event 顧名思義,是由伺服器端主動推送到客戶端,它是單項式的,對於雙向的聊天來說,相對沒有這麼合適,因為聊天的傳訊是雙向的。Server-sent Event 一般比較適合在通知系統,這種單向從伺服器傳到客戶端的情境。
第三個是 WebSocket
WebSocket 是個雙向的協定,且具有長連接的特性,對於即時聊天來說,是相當適合的一種協定,目前多數業界的聊天系統也會選擇 WebSocket 作為處理即時聊天的部分。
當保持著 WebSocket 的連接,客戶端可以主動傳訊息給伺服器端,伺服器端也可以主動傳訊息給客戶端。也因為是長連接,WebSocket 少掉需要重新建立連接的步驟,這能同時減輕 auth
部分的服務壓力。
本文為 E+ 成長計畫的深度內容,截取前三分之一開放免費閱讀。歡迎加入 E+ 成長計畫閱讀完整版本 (點此了解 E+ 的詳細介紹)