IM消息系统的设计和实现是怎样的
這篇文章給大家介紹IM消息系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)是怎樣的,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。一、名詞解釋
-
單播:服務(wù)器發(fā)送消息給單個(gè)客戶端用戶
-
多播:服務(wù)器發(fā)送消息給多個(gè)客戶端用戶
-
組播/廣播:服務(wù)器發(fā)送消息給一組客戶端。有組ID來標(biāo)識(shí)這組用戶
-
上行消息:服務(wù)器發(fā)送消息給一組客戶端。有組ID來標(biāo)識(shí)這組用戶
-
下行消息:服務(wù)器端給客戶端發(fā)送消息
二、系統(tǒng)架構(gòu)
-
proxy:部署在邊緣機(jī)房,客戶端通過智能dns就近接入
-
logicService:處理認(rèn)證、心跳、上下線、進(jìn)出群
-
pushService:單播,廣播,接收到消息后轉(zhuǎn)發(fā)給comet,之后再由comet把消息發(fā)出去
-
imService:聊天服務(wù)器,處理單聊群聊,離線消息
-
cosumerService:對(duì)群消息進(jìn)行異步寫擴(kuò)散
-
authService:認(rèn)證服務(wù)
數(shù)據(jù)結(jié)構(gòu)
user_id -> conn_id -> server_id。-
user_id 是業(yè)務(wù)指定的,唯一標(biāo)識(shí)一個(gè)用戶
-
conn_id 由存儲(chǔ)進(jìn)程分配,唯一標(biāo)識(shí)該用戶的一條連接
-
server_id 標(biāo)識(shí)這條連接屬于哪個(gè)接入進(jìn)程
user_id+conn_id -> Connection-
Connection 是客戶端連接的封裝,可以向它推送消息
room_id -> ConnectionList三、消息模型
3.1 讀擴(kuò)散模型
-
優(yōu)點(diǎn):只寫一次,降低了寫入次數(shù),特別在群模式下
-
缺點(diǎn): 同步消息的邏輯會(huì)比較復(fù)雜,接收端每個(gè)會(huì)話都要讀取一次,放大了讀,會(huì)產(chǎn)生很多無效請(qǐng)求。
3.2 寫擴(kuò)散模型
-
優(yōu)點(diǎn):拉取消息的邏輯簡(jiǎn)單
-
缺點(diǎn): 放大了寫,單聊要額外寫兩次,群里要寫N次
四、實(shí)現(xiàn)方式
4.1 單聊
4.1.1 設(shè)計(jì)目標(biāo)
4.1.2 在線消息
4.1.3 離線消息
4.1.4 檢測(cè)消息丟失
4.2 群聊
4.2.1 設(shè)計(jì)目標(biāo)
4.2.2 小群(寫擴(kuò)散)
4.2.3 大群(讀擴(kuò)散)
五、高性能分析
5.1 容量規(guī)劃:(阿里云主機(jī)16C32G-2.5GHz,預(yù)留50%余量)
-
10,000 conn per proxy
-
100 proxy
-
50 logicService/cacheService/pushService
-
or 改進(jìn):
-
10 logicService
-
5 pushService
-
kafka cluster
-
zookeeper cluster
-
10 cacheService
5.2內(nèi)部通信無瓶頸,可水平擴(kuò)容的路徑有:
-
客戶端發(fā)起的RPC mobile -> proxy -> micro
-
上線/下線/切換房間/心跳 mobile -> proxy -> logicService -> cacheService
-
單播 micro -> logicService (-> cacheService) -> pushService -> proxy -> mobile
-
在線信息查詢
-
按用戶查在線查房間 /session
5.3 內(nèi)部通信,可能有瓶頸的路徑:
-
批量單播 micro -> logicService ((N-parallel)-> router) -> pushService -> proxy -> mobile
-
限制:一批用戶總數(shù),不宜過多
-
廣播 micro -> logicService -> pushService -> proxy -> mobile
-
限制:由于pushService定期absorb proxy上的room list, so pushService數(shù)量不可過多
-
改進(jìn):logicService和pushService解耦,用kafka連接。由于 pushService 對(duì) CPU 的消耗在 proxy/logicService/cacheService 中最少,只需要非常少的 pushService 實(shí)例就行。
-
在線信息查詢
-
查在線總數(shù) /count 由于logicService定期absorb cacheService上的room users,只能是有限的logicService打開counter定時(shí)查
-
按房間查用戶 /room 同 /count
-
遍歷 /list 調(diào)試用接口,別用于服務(wù)
5.4 proxy性能瓶頸
5.5 rpc性能瓶頸
六、高可用分析
-
proxy 無狀態(tài)服務(wù),重啟、升級(jí)時(shí),客戶端檢測(cè)到連接斷開,自動(dòng)重連到另一個(gè) proxy
-
logicService 無狀態(tài)服務(wù),重啟、升級(jí)時(shí),proxy 會(huì)自動(dòng)尋找下一個(gè) logic
-
pushService 無狀態(tài)服務(wù),重啟、升級(jí)時(shí),有其它 pushService對(duì)外提供服務(wù)
-
cacheService 有狀態(tài)服務(wù),重啟、升級(jí)時(shí),由備 cacheService 頂上;升級(jí)完成,切回主 cacheService
-
imService 無狀態(tài)服務(wù),重啟、升級(jí)時(shí),有其它 pushService對(duì)外提供服務(wù)
-
mysql:使用mysql master master機(jī)制來保證
-
redis: 使用哨兵機(jī)制來保證可用性
七、異常情況處理
-
如何防止消息丟失(接收端上報(bào)已接收的最大消息id,異常服務(wù)端重發(fā))
-
redis主從切換引起自增id不連續(xù)
-
怎么提高proxy廣播的性能
-
怎么避免rpc的單條連接成為瓶頸
八、低成本、安全
-
幾乎沒有外部依賴,極低的運(yùn)維成本
-
高性能的代碼實(shí)現(xiàn),節(jié)省服務(wù)器成本
-
集成認(rèn)證鑒權(quán),也支持 HTTPS
總結(jié)
以上是生活随笔為你收集整理的IM消息系统的设计和实现是怎样的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Eclipse 报java.lang.O
- 下一篇: Spark Streaming揭秘 Da