日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

一个海量在线用户即时通讯系统(IM)的完整设计

發布時間:2023/12/20 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个海量在线用户即时通讯系统(IM)的完整设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CSDN博客有圖片大小限制,有些圖片無法顯示,可查看微信公眾號中原文。


1 服務器端設計


1.1 總體架構

總體架構包括5個層級,具體內容如下圖。


1.1.1 用戶端

移動端重點是移動端,支持IOS/Android系統,包括IM App,嵌入消息功能的瓜子App,未來還可能接入客服系統。


1.1.2 用戶端API

針對TCP協議,提供IOS/Android開發SDK。對于H5頁面,提供WebSocket接口


1.1.3 接入層

接入層主要任務是保持海量用戶連接(接入)、攻擊防護、將海量連接整流成少量TCP連接與邏輯層通訊。


1.1.4 邏輯層

邏輯層負責IM系統各項功能的核心邏輯實現。包括單聊(c2c)、上報(c2s)、推送(s2c)、群聊(c2g)、離線消息、登錄授權、組織機構樹等等內容。


1.1.5 存儲層

存儲層負責緩存或存儲IM系統相關數據,主要包括用戶狀態及路由(緩存),消息數據(MySQL也可采用NoSql,如MangoDB),文件數據(文件服務器)。


1.2 邏輯結構


1.2.1 核心結構

核心結構部分描述IM系統核心組件及其關系。結構圖如下。


客戶端從Iplist服務獲取接入層IP地址(也可采用域名的方式解析得到接入層IP地址),建立與接入層的連接(可能為短連接),從而實現客戶端與IM服務器的數據交互;業務線服務器可以通過服務器端API建立與IM服務器的聯系,向客戶端推送消息;客戶端上報到業務服務器的消息,IM服務器會通過mq投遞給業務服務器。


1.2.2 tcp接入核心流程


1.2.2.1 登錄授權(auth)

1、客戶端通過統一登錄系統實現登錄,得到token。

2、客戶端用uid和token向msg-gate發起授權驗證請求。

3、msg-gate同步調用msg-logic的驗證接口

4、msg-logic請求sso系統驗證token合法性

5、msg-gate得到登錄結果后,設置session狀態,并向客戶端返回授權結果。


1.2.2.2 登出(logout)

1、客戶端發起logout請求,msg-gate設置對應Peer為未登錄狀態。

2、Msg-gate給客戶端一個ack響應。

3、Msg-gate通知msg-logic用戶登出。


1.2.2.3踢人(kickout)

用戶請求授權時,可能在另一個設備(同類型設備)開著軟件處于登錄狀態。這種情況需要系統將那個設備踢下線。

1-5步,參看Auth流程。

6、Logic檢索Redis,查看是否該用戶在其他地方登錄。

7、如果在其他地方登錄,發起kickout命令。(如果沒有登錄,整個流程結束)

8、Gate向用戶發起kickout請求,并在短時間內(確保客戶端收到kickout數據)關閉socket連接。


1.2.2.4 上報(c2s)

?

1、客戶端向gate發送數據

2、Gate回一個ack包,向客戶端確認已經收到數據

3、Gate將數據包傳遞給logic

4、Logic根據數據投遞目的地,選擇對應的mq隊列進行投遞

5、業務服務器得到數據


1.2.2.5推送(s2c)

1、業務線調用push數據接口sendMsg

2、Logic向redis檢索目標用戶狀態。如果目標用戶不在線,丟棄數據(未來可根據業務場景定制化邏輯);如果用戶在線,查詢到用戶連接的接入層gate

3、Logic向用戶所在的gate發送數據

4、Gate向用戶推送數據。(如果用戶不在線,通知logic用戶不在線)

5、客戶端收到數據后向gate發送ack反饋

6、Gate將ack信息傳遞給logic層,用于其他可能的邏輯處理(如日志,確認送達等)


1.2.2.6單對單聊天(c2c)

1、App1向gate1發送信息(信息最終要發給App2)

2、Gate1將信息投遞給logic

3、Logic收到信息后,將信息進行存儲

4、存儲成功后,logic向gate1發送ack

5、Gate1將ack信息發給App1

6、Logic檢索redis,查找App2狀態。如果App2未登錄,流程結束

7、如果App2登錄到了gate2,logic將消息發往gate2

8、Gate2將消息發給App2(如果發現App2不在線,丟棄消息即可,這種概率極低,后續離線消息可保證消息不丟)

9、App2向gate2發送ack

10、Gate2將ack信息發給logic

11、Logic將消息狀態設置為已送達。

注:在第6步和第7步之間,啟動計時器(DelayedQueue或哈希環,時間如5秒),計時器時間到后,探測該條消息狀態,如果消息未送達,考慮通過APNS、米推、個推進行推送


1.2.2.7 群聊(c2g)

采用擴散寫(而非擴散讀)的方式。

群聊是多人社交的基本訴求,一個群友在群內發了一條消息:

(1)在線的群友能第一時間收到消息

(2)離線的群友能在登陸后收到消息

由于“消息風暴擴散系數”的存在,群消息的復雜度要遠高于單對單消息。

群基礎表:用來描述一個群的基本信息

im_group_msgs(group_id, group_name,create_user, owner, announcement, create_time)

群成員表:用來描述一個群里有多少成員

im_group_users(group_id, user_id)

用戶接收消息表:用來描述一個用戶的所有收到群消息(與單對單消息表是同一個表)

im_message_recieve(msg_id,msg_from,msg_to, group_id,msg_seq, msg_content, send_time, msg_type, deliverd, cmd_id)

用戶發送消息表:用來描述一個用戶發送了哪些消息

im_message_send (msg_id,msg_from,msg_to, group_id,msg_seq, msg_content, send_time, msg_type, cmd_id)

業務場景舉例:

(1)一個群中有x,A,B,C,D共5個成員,成員x發了一個消息

(2)成員A與B在線,期望實時收到消息

(3)成員C與D離線,期望未來拉取到離線消息

群聊流程如下圖所示

1、X向gate發送信息(信息最終要發給這個群,A、B在線)

2、Gate將消息發給logic

3、存儲消息到im_message_send表,按照msg_from水平分庫

4、回ack

5、回ack

6、Logic檢索數據庫(需要使用緩存),獲得群成員列表

7、存儲每個用戶的消息數據(用戶視圖),按照msg_to水平分庫(并發、批量寫入)。

8、查詢用戶在線狀態及位置

9、Logic向gate投遞消息

10、Gate向用戶投遞消息

11、App返回收到消息的ack信息

12、Gate向logic傳遞ack信息

13、向緩存(Hash)中更新收到ack的時間。然后在通過一個定時任務,每隔一定時間,將數據更新到數據庫(注意只需要寫入時間段內有變化的數據)。


1.2.2.8拉取離線消息

下圖中,將gate和logic合并為im-server。拉取離線消息流程如下。?

1、App端登錄成功后(或業務觸發拉取離線消息),向IM系統發起拉離線消息請求。傳遞3個主要參數,uid表明用戶;msgid表明當前收到的最大消息id(如果沒收到過消息,或拿不到最大消息id則msgid=0)即可;size表示每次拉取條數(這個值也可以由服務器端控制)。

2、假設msgid==0,什么都不做。(參看第6步驟)

3、Im-server查詢用戶前10條離線消息

4、將離線消息推給用戶。假設這10條離線消息最大msgid=110。

5、App得到數據,判斷得到的數據不為空(表明可能沒有拉完離線數據,不用<10條做判斷拉完條件,因為服務端需要下下次拉離線的請求來確定這次數據已送達),繼續發起拉取操作。Msgid=110(取得到的離線消息中最大的msgid)。

6、Im-server刪除該用戶msgid<110的離線消息(或者標記為已送達)。

7、查詢msgid>110的錢10條離線數據。

8、返回給App

……

N-1、查詢msgid>140的離線數據,0條(沒有離線數據了)。

N ?、將數據返回App,App判斷拉取到0條數據,結束離線拉取過程。


1.2.3 PUSH

ISO采用APNS;Android真后臺保活,同時增加米推、個推。

基本思路:push提示信息,App通過拉離線獲得真實消息。

另附文檔說明此問題。


2 協議設計


2.1 TCP數據協議

TCP的數據協議如下圖所示。包括header和body兩部分。


消息頭總共20個字節,具體信息如下表。


2.2TCP消息體設計

消息體協議采用ProtocolBuffer(谷歌)協議,版本3.0.0,該協議在序列化效率、壓縮、可擴展方面都具有優勢。協議條目見附錄11.1.1TCP協議命令清單。以下為主要流程涉及的協議


2.2.1 認證(auth)?


2.2.2?登出(logout)

?


2.2.3 踢人(kickout)?


2.2.4 心跳(keepalive,noop)

心跳包消息體為空。


2.2.5單對單聊天(c2c)

?


2.2.6群聊(c2g)

?

2.2.7拉離線(pull)

2.2.8控制類(ctrl)

?


3 存儲設計

3.1MySQL數據庫

MySQL數據庫采用utf8mb4編碼格式(emoji字符問題)

3.1.1主要表結構

3.1.1.1發送消息表

保存某個用戶發送了哪些消息,用于復現用戶聊天場景(消息漫游功能需要)。

3.1.1.2推送消息表

保存某個用戶收到了哪些消息


3.1.1.3群相關表

群基本信息表


群用戶關系表


3.1.2 水平分庫


3.2Redis緩存


3.2.1用戶狀態及路由信息

Redis緩存以uid為key,檢索channel(socketid),last_packet_time等。

Gate層,session以channel(socketed)為key,檢索uid,及其他信息。

交互接口:gate->logic,通過將channel轉換為uid作為key。

logic->gate,將uid轉換為channel作為key。


3.2.2其他緩存信息

你覺得該怎么存就怎么存。


3.3文件及圖片存儲

采用商用云存儲。


3.4數據歸檔

可考慮采用HBase,HDFS作為數據歸檔,或者相關云存儲服務。


安全部分略,其他非核心功能略


相關閱讀

《IM系統的SESSION結構》

《IM系統如何調試TCP協議》

《NAT是怎么回事》

《視頻聊天功能如何穿透NAT》

IM移動端怎么搜索本地聊天記錄


·END·

碼農吹牛逼

互聯網相關技術



微信ID:farmerbrag



總結

以上是生活随笔為你收集整理的一个海量在线用户即时通讯系统(IM)的完整设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。