日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
微信為啥不丟“離線消息”?

需求緣起

成都創(chuàng)新互聯(lián)公司主營棗強(qiáng)網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都app軟件開發(fā),棗強(qiáng)h5重慶小程序開發(fā)搭建,棗強(qiáng)網(wǎng)站營銷推廣歡迎棗強(qiáng)等地區(qū)企業(yè)咨詢

當(dāng)發(fā)送方用戶A發(fā)送消息給接收方用戶B時(shí),如果用戶B在線,之前的文章《微信為啥不丟“在線消息”?》聊過,可以通過應(yīng)用層的確認(rèn),發(fā)送方的超時(shí)重傳,接收方的去重保證業(yè)務(wù)層面消息的不丟不重。

那如果接收方用戶B不在線,系統(tǒng)是如何保證消息的可達(dá)性的呢?這是本文要討論的問題。

問題:接收方不在線時(shí),消息發(fā)送的流程是怎么樣的?

回答:如上圖所述,

(1)用戶A發(fā)送消息給用戶B

(2)服務(wù)器查看用戶B的狀態(tài)為offline

(3)服務(wù)器將消息存儲(chǔ)到DB中

(4)服務(wù)器返回用戶A發(fā)送成功(對于發(fā)送方而言,消息落地DB就認(rèn)為發(fā)送成功)

問題:離線消息表的設(shè)計(jì),拉取離線的過程?

receiver_uid, msg_id, time, sender_uid,msg_type, msg_content …

訪問模式:接收方B要拉取發(fā)送方A給ta發(fā)送的離線消息,只需在receiver_uid(B), sender_uid(A)上查詢,然后把離線消息刪除,再把消息返回B即可。

整體流程如上圖所述,

(1)用戶B拉取用戶A發(fā)送給ta的離線消息

(2)服務(wù)器從DB中拉取離線消息

(3)服務(wù)器從DB中把離線消息刪除

(4)服務(wù)器返回給用戶B想要的離線消息

問題:上述流程存在的問題?

回答:如果用戶B有很多好友,登陸時(shí)客戶端需要對所有好友進(jìn)行離線消息拉取,客戶端與服務(wù)器交互次數(shù)較多

客戶端偽代碼:

 
 
  1. for(all uid in B’s friend-list){ // 登陸時(shí)所有好友都要拉取
  2. get_offline_msg(B,uid); // 與服務(wù)器交互
  3. }

優(yōu)化方案一:先拉取各個(gè)好友的離線消息數(shù)量,真正用戶B進(jìn)去看離線消息時(shí),才往服務(wù)器發(fā)送拉取請求(手機(jī)端為了節(jié)省流量,經(jīng)常會(huì)使用這個(gè)按需拉取的優(yōu)化)

優(yōu)化方案二:一次性拉取所有好友發(fā)送給用戶B的離線消息,到客戶端本地再根據(jù)sender_uid進(jìn)行計(jì)算,這樣的話,離校消息表的訪問模式就變?yōu)?>只需要按照receiver_uid來查詢了。登錄時(shí)與服務(wù)器的交互次數(shù)降低為了1次。

問題:用戶B一次性拉取所有好友發(fā)給ta的離線消息,消息量很大時(shí),一個(gè)請求包很大,速度慢,容易卡頓怎么辦?

回答:分頁拉取,根據(jù)業(yè)務(wù)需求,先拉取***(或者最舊)的一頁消息,再按需一頁頁拉取。

問題:如何保證可達(dá)性,上述步驟第三步執(zhí)行完畢之后,第四個(gè)步驟離線消息返回給客戶端過程中,服務(wù)器掛點(diǎn),路由器丟消息,或者客戶端crash了,那離線消息豈不是丟了么(數(shù)據(jù)庫已刪除,用戶還沒收到)?

回答:嗯,如果按照上述的1,2,3,4步流程,的確是的,那如何保證離線消息的可達(dá)性?

如同在線消息的應(yīng)用層ACK機(jī)制一樣,離線消息拉時(shí),不能夠直接刪除數(shù)據(jù)庫中的離線消息,而必須等應(yīng)用層的離線消息ACK(說明用戶B真的收到離線消息了),才能刪除數(shù)據(jù)庫中的離線消息。

問題:如果用戶B拉取了一頁離線消息,卻在ACK之前crash了,下次登錄時(shí)會(huì)拉取到重復(fù)的離線消息么?

回答:拉取了離線消息卻沒有ACK,服務(wù)器不會(huì)刪除之前的離線消息,故下次登錄時(shí)系統(tǒng)層面還會(huì)拉取到。但在業(yè)務(wù)層面,可以根據(jù)msg_id去重。SMC理論:系統(tǒng)層面無法做到消息不丟不重,業(yè)務(wù)層面可以做到,對用戶無感知。

問題:假設(shè)有N頁離線消息,現(xiàn)在每個(gè)離線消息需要一個(gè)ACK,那么豈不是客戶端與服務(wù)器的交互次數(shù)又加倍了?有沒有優(yōu)化空間?

回答:不用每一頁消息都ACK,在拉取第二頁消息時(shí)相當(dāng)于***頁消息的ACK,此時(shí)服務(wù)器再刪除***頁的離線消息即可,***一頁消息再ACK一次。這樣的效果是,不管拉取多少頁離線消息,只會(huì)多一個(gè)ACK請求,與服務(wù)器多一次交互。

總結(jié)

“離線消息”的可達(dá)性可能比大家想象的要復(fù)雜,常見的優(yōu)化有:

(1)對于同一個(gè)用戶B,一次性拉取所有用戶發(fā)給ta的離線消息,再在客戶端本地進(jìn)行發(fā)送方分析,相比按照發(fā)送方一個(gè)個(gè)進(jìn)行消息拉取,能大大減少服務(wù)器交互次數(shù)

(2)分頁拉取,先拉取計(jì)數(shù)再按需拉取,是無線端的常見優(yōu)化

(3)應(yīng)用層的ACK,應(yīng)用層的去重,才能保證離線消息的不丟不重

(4)下一頁的拉取,同時(shí)作為上一頁的ACK,能夠極大減少與服務(wù)器的交互次數(shù)

文章轉(zhuǎn)載自微信公眾號“架構(gòu)師之路”


分享題目:微信為啥不丟“離線消息”?
瀏覽路徑:http://www.5511xx.com/article/cdjpoop.html