成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

群消息這么復雜,怎么能做到不丟不重?

開發 開發工具
由于“消息風暴擴散系數”的存在(概念詳見《QQ狀態同步究竟是推還是拉?》),群消息的復雜度要遠高于單對單消息。群消息的實時性,可達性,離線消息是今天將要討論的核心話題。

[[175957]]

【需求緣起】

之前的文章更多的聊了單對單的消息投遞:

微信為什么不丟消息?

http如何像tcp一樣實時的收消息?

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

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

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

由于“消息風暴擴散系數”的存在(概念詳見《QQ狀態同步究竟是推還是拉?》),群消息的復雜度要遠高于單對單消息。群消息的實時性,可達性,離線消息是今天將要討論的核心話題。

【常見的群消息流程】

開始講群消息投遞流程之前,先介紹兩個群業務的核心數據結構:

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

t_group_users(group_id, user_id)

群離線消息表:用來描述一個群成員的離線消息

t_offine_msgs(user_id, group_id, sender_id,time, msg_id, msg_detail)

業務場景舉例:

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

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

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

系統架構簡介:

(1)客戶端:x,A,B,C,D共5個客戶端用戶

(2)服務端

(2.1)所有模塊與服務抽象為server

(2.2)所有用戶在線狀態抽象存儲在高可用cache里

(2.3)所有數據信息,例如群成員、群離線消息抽象存儲在db里

典型群消息投遞流程,如圖步驟1-4所述:

步驟1:群消息發送者x向server發出群消息

步驟2:server去db中查詢群中有多少用戶(x,A,B,C,D)

步驟3:server去cache中查詢這些用戶的在線狀態

步驟4:對于群中在線的用戶A與B,群消息server進行實時推送

步驟5:對于群中離線的用戶C與D,群消息server進行離線存儲

典型的群離線消息拉取流程,如圖步驟1-3所述:

步驟1:離線消息拉取者C向server拉取群離線消息

步驟2:server從db中拉取離線消息并返回群用戶C

步驟3:server從db中刪除群用戶C的群離線消息

存在的問題

上述流程是最容易想,也最容易理解的,存在的問題也最顯而易見:對于同一份群消息的內容,多個離線用戶存儲了很多份。假設群中有200個用戶離線,離線消息則冗余了200份,這極大的增加了數據庫的存儲壓力。

【群消息優化1:減少存儲量】

為了減少離線消息的冗余度,增加一個群消息表,用來存儲所有群消息的內容,離線消息表只存儲用戶的群離線消息msg_id,就能大大的降低數據庫的冗余存儲量

群消息表:用來存儲一個群中所有的消息內容

t_group_msgs(group_id, sender_id, time,msg_id, msg_detail)

群離線消息表:優化后只存儲msg_id

t_offine_msgs(user_id, group_id, msg_id)

這樣優化后,群在線消息發送就做了一些修改:

步驟3:每次發送在線群消息之前,要先存儲群消息的內容

步驟6:每次存儲離線消息時,只存儲msg_id,而不用為每個用戶存儲msg_detail

拉取離線消息時也做了響應的修改:

步驟1:先拉取所有的離線消息msg_id

步驟3:再根據msg_id拉取msg_detail

步驟5:刪除離線msg_id

存在的問題

如同單對單消息的發送一樣:

(1)在線消息的投遞可能出現消息丟失,例如服務器重啟,路由器丟包,客戶端crash

(2)離線消息的拉取也可能出現消息丟失,原因同上

需要和單對單消息的可靠投遞一樣,加入應用層的ACK,才能保證群消息一定到達。

【群消息優化2:應用層ACK】

應用層ACK優化后,群在線消息發送又發生了一些變化:

步驟3:在消息msg_detail存儲到群消息表后,不管用戶是否在線,都先將msg_id存儲到離線消息表里

步驟6:在線的用戶A和B收到群消息后,需要增加一個應用層ACK,來標識消息到達

步驟7:在線的用戶A和B在應用層ACK后,將他們的離線消息msg_id刪除掉

對應到群離線消息的拉取也一樣:

步驟1:先拉取msg_id

步驟3:再拉取msg_detail

步驟5:***應用層ACK

步驟6:server收到應用層ACK才能刪除離線消息表里的msg_id

存在的問題

(1)如果拉取了消息,卻沒來得及應用層ACK,會收到重復的消息么?

回答:會,可以在客戶端去重,對于重復的msg_id,對用戶不展現,從而不影響用戶體驗

(2)對于離線的每一條消息,雖然只存儲了msg_id,但是每個用戶的每一條離線消息都將在數據庫中保存一條記錄,有沒有辦法減少離線消息的記錄數呢?

【群消息優化3:離線消息表】

離線消息表的優化

其實,對于一個群用戶,在ta登出后的離線期間內,肯定是所有的群消息都沒有收到的,完全不用對所有的每一條離線消息存儲一個離線msg_id,而只需要存儲最近一條拉取到的離線消息的time(或者msg_id),下次登錄時拉取在那之后的所有群消息即可,而完全沒有必要存儲每個人未拉取到的離線消息msg_id

群成員表:用來描述一個群里有多少成員,以及每個成員***一條ack的群消息的msg_id(或者time)

t_group_users(group_id, user_id, last_ack_msg_id(last_ack_msg_time))

群消息表:用來存儲一個群中所有的消息內容,不變

t_group_msgs(group_id, sender_id, time,msg_id, msg_detail)

群離線消息表:不再需要了

離線消息表優化后,群在線消息的投遞流程:

步驟3:在消息msg_detail存儲到群消息表后,不再需要操作離線消息表(優化前需要將msg_id插入離線消息表)

步驟7:在線的用戶A和B在應用層ACK后,將last_ack_msg_id更新即可(優化前需要將msg_id從離線消息表刪除)

群離線消息的拉取流程也類似:

步驟1:拉取離線消息

步驟3:ACK離線消息

步驟4:更新last_ack_msg_id

存在的問題

由于“消息風暴擴散系數”的存在,假設1個群有500個用戶,“每條”群消息都會變為500個應用層ACK,將對服務器造成巨大的沖擊,有沒有辦法減少ACK請求量呢?

【群消息優化4:批量ACK】

由于“消息風暴擴散系數”的存在,如果每條群消息都ACK,會給服務器造成巨大的沖擊,為了減少ACK請求量,很容易想到的方法是批量ACK。

批量ACK的方式又有兩種:

(1)每收到N條群消息ACK一次,這樣請求量就降低為原來的1/N了

(2)每隔時間間隔T進行一次群消息ACK,也能達到類似的效果

新的問題

批量ACK有可能導致:還沒有來得及ACK群消息,用戶就退出了,這樣下次登錄會拉取到重復的離線消息

解決方案

msg_id去重,不對用戶展現,保證良好的用戶體驗

還可能存在的問題

群離線消息過多:拉取過慢

解決方案:分頁拉取(按需拉取),分頁拉取的細節在“微信為啥不丟離線消息”一章中有詳細敘述,此處不再展開(詳見《微信為啥不丟“離線消息”?》)。

【總結】

群消息還是非常有意思的,可達性、實時性、離線消息、消息風暴擴散等等等等,做個總結:

(1)不管是群在線消息,還是群離線消息,應用層的ACK是可達性的保障

(2)群消息只存一份,不用為每個用戶存儲離線群msg_id,只需存儲一個最近ack的群消息id/time

(3)為了減少消息風暴,可以批量ACK

(4)如果收到重復消息,需要msg_id去重,讓用戶無感知

(5)離線消息過多,可以分頁拉取(按需拉取)優化

文章轉載自微信公眾號“架構師之路”

責任編輯:趙寧寧 來源: 架構師之路
相關推薦

2025-06-12 09:46:15

2025-04-17 09:00:00

架構聊消息微信

2016-10-11 16:31:56

微信服務器消息

2016-11-02 13:12:31

微信離線消息

2021-03-08 10:19:59

MQ消息磁盤

2024-01-16 08:24:59

消息隊列KafkaRocketMQ

2015-12-11 10:27:50

易維幫助臺/Helpd

2020-10-26 09:19:11

線程池消息

2015-11-17 09:41:38

私有云自動化應用部署

2025-03-31 10:49:16

2024-06-18 08:26:22

2011-05-25 20:48:23

seo

2017-02-27 18:20:30

Amazon持續交付

2019-08-21 07:44:32

離線消息拉取開發

2016-12-27 19:26:43

2018-01-05 10:47:59

前端JavascriptWeb

2020-03-31 09:53:08

互聯網數據技術

2020-02-24 13:06:55

Python數據幀開發

2022-04-21 14:43:59

AI數據隱私

2020-01-03 08:48:02

RocketMQ訂單系統MQ
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产最好的av国产大片 | 视频在线h | 黄色网毛片 | 99re在线视频 | 亚洲成年影院 | 国产一区二区三区在线免费观看 | 97av视频 | 日本久久网站 | 在线观看三级av | 欧美在线观看网站 | 最新av中文字幕 | 国产成人精品一区二区三区在线 | 国内精品久久影院 | 一区二区三区在线 | 成年人在线播放 | 日本精品国产 | 毛片一级黄色 | 国产 日韩 欧美 在线 | 国产精品一区二区三区久久久 | 午夜精品 | 精品国产一区二区三区久久久四川 | 日韩精品激情 | 国产激情片在线观看 | 亚洲乱码一区二区三区在线观看 | 一级毛片视频免费观看 | 亚洲综合成人网 | 国产成人福利 | 夜夜骑av| 久久69精品久久久久久国产越南 | 国产精品高清一区二区三区 | 天天操夜夜爽 | 超碰美女在线 | 在线视频国产一区 | 欧美毛片免费观看 | 久久国产欧美日韩精品 | 精品久久香蕉国产线看观看亚洲 | 成人视屏在线观看 | 久久的色 | 亚洲欧美在线一区 | 亚洲视频免费在线观看 | 亚洲自拍偷拍免费视频 |