偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

群消息已讀回執(zhí),為什么這么難?

開(kāi)發(fā) 架構(gòu)
群消息的流程如何,接收方如何確保收到群消息,發(fā)送方如何收已讀回執(zhí),究竟是拉取,還是推送,是今天要聊的話題。

場(chǎng)景描述:

  • 每當(dāng)發(fā)出一條微信消息,都希望對(duì)方盡快看到,并盡快回復(fù),但始終不知道對(duì)方是否閱讀。
  • 微信用于個(gè)人社交,產(chǎn)品設(shè)計(jì)上,在線狀態(tài),強(qiáng)制已讀回執(zhí)都有可能暴露個(gè)人隱私,故微信并無(wú)相關(guān)功能。
  • 釘釘用于商務(wù)交流,其“強(qiáng)制已讀回執(zhí)”功能,讓職場(chǎng)人無(wú)法再“假裝不在線”,“假裝沒(méi)收到”。

群消息的流程如何,接收方如何確保收到群消息,發(fā)送方如何收已讀回執(zhí),究竟是拉取,還是推送,是今天要聊的話題。

一、群消息投遞流程,以及可達(dá)性保證

核心問(wèn)題1:群消息,只存一份?還是,每個(gè)成員存一份?

答:存一份,為每個(gè)成員設(shè)置一個(gè)群消息隊(duì)列,會(huì)有大量數(shù)據(jù)冗余,并不合適。

核心問(wèn)題2:如果群消息只存一份,怎么知道每個(gè)成員讀了哪些消息?

答:可以利用群消息的偏序關(guān)系,記錄每個(gè)成員的last_ack_msgid(last_ack_time),這條消息之前的消息已讀,這條消息之后的消息未讀。

該方案意味著,對(duì)于群內(nèi)的每一個(gè)用戶,只需要記錄一個(gè)值即可。

解答上述兩個(gè)核心問(wèn)題后,很容易得到群消息的核心數(shù)據(jù)結(jié)構(gòu)。

群消息表:記錄群消息。

group_msgs(msgid, gid, sender_uid, time, content);

各字段的含義為:消息ID,群ID,發(fā)送方UID,發(fā)送時(shí)間,發(fā)送內(nèi)容。

群成員表:記錄群里的成員,以及每個(gè)成員收到的最后一條群消息。

group_users(gid, uid, last_ack_msgid);

各字段的含義為:群ID,群成員UID,群成員最后收到的一條群消息ID。

在核心數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)完之后,一起來(lái)看看群消息發(fā)送的流程。

業(yè)務(wù)場(chǎng)景假設(shè):

  • 一個(gè)群中有A, uid1, uid2, uid3四名成員;
  • A, uid1, uid2在線,期望實(shí)時(shí)收到在線消息;
  • uid3離線,期望未來(lái)拉取到離線消息;

其整個(gè)消息發(fā)送的流程1-4如上圖:

  • A發(fā)出群消息;
  • server收到消息后,一來(lái)要將群消息落地,二來(lái)要查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送;
  • 對(duì)于群成員,查詢?cè)诰€狀態(tài);
  • 對(duì)于在線的群成員,實(shí)施推送;

這個(gè)流程里,只要第二步消息落地完成,就能保證群消息不會(huì)丟失。

核心問(wèn)題3:如何保證接收方一定收到群消息?

答:各個(gè)收到消息后,要修改各群成員的last_ack_msgid,以告訴系統(tǒng),這一條消息確認(rèn)收到了。

在線消息,離線消息的last_ack_msgid的修改,又各有不同。

對(duì)于在線的群友,收到群消息后,第一時(shí)間會(huì)ack,修改last_ack_msgid。

對(duì)于離線的群友,會(huì)在下一次登錄時(shí),拉取未讀的所有群離線消息,并將last_ack_msgid修改為最新的一條消息。

核心問(wèn)題4:如果ack丟失,群友會(huì)不會(huì)拉取重復(fù)的群消息?

答:會(huì),可以根據(jù)msgid在客戶端本地做去重,即使系統(tǒng)層面收到了重復(fù)的消息,仍然可以保證良好的用戶體驗(yàn)。

上述流程,只能確保接收方收到消息,發(fā)送方仍然不知道哪些人在線閱讀了消息,哪些人離線未閱讀消息,并沒(méi)有實(shí)現(xiàn)已讀回執(zhí),那已讀回執(zhí)會(huì)對(duì)系統(tǒng)設(shè)計(jì)產(chǎn)生什么樣的影響呢?

二、已讀回執(zhí)流程

對(duì)于發(fā)送方發(fā)送的任何一條群消息,都需要知道,這條消息有多少人已讀多少人未讀,就需要一個(gè)基礎(chǔ)表來(lái)記錄這個(gè)關(guān)系。

消息回執(zhí)表:用來(lái)記錄消息的已讀回執(zhí)。

msg_acks(sender_uid, msgid, recv_uid, gid,if_ack);

各字段的含義為:發(fā)送方UID,消息ID,回執(zhí)方UID,群ID,回執(zhí)標(biāo)記。

增加了已讀回執(zhí)邏輯后,群消息的流程會(huì)有細(xì)微的改變。

步驟二,server收到消息后,除了要:

  • 將群消息落地;
  • 查詢?nèi)豪镉心男┤撼蓡T,以便實(shí)施推送;

之外,還需要:

  • 插入每條消息的初始回執(zhí)狀態(tài);

接收方修改last_ack_msgid的流程,會(huì)變?yōu)椋?/p>

  • 發(fā)送ack請(qǐng)求;
  • 修改last_ack_msgid,并且,修改已讀回執(zhí)if_ack狀態(tài);
  • 查詢發(fā)送方在線狀態(tài);
  • 向發(fā)送方實(shí)時(shí)推送已讀回執(zhí)(如果發(fā)送方在線);

如果發(fā)送方不在線,ta會(huì)在下次登錄的時(shí)候:

  • 從關(guān)聯(lián)表里拉取每條消息的已讀回執(zhí);

這里的初步結(jié)論是:

  • 如果發(fā)送方在線,會(huì)實(shí)時(shí)被推送已讀回執(zhí);
  • 如果發(fā)送方不在線,會(huì)在下次在線時(shí)拉取已讀回執(zhí);

三、流程優(yōu)化方案

再次詳細(xì)的分析下,群消息已讀回執(zhí)的“消息風(fēng)暴擴(kuò)散系數(shù)”,假設(shè)每個(gè)群有200個(gè)用戶,其中20%的用戶在線,即40各用戶在線。群用戶每發(fā)送一條群消息,會(huì)有:

  • 40個(gè)消息,通知給群友;
  • 40個(gè)ack修改last_ack_msgid,發(fā)給服務(wù)端;
  • 40個(gè)已讀回執(zhí),通知給發(fā)送方;

可見(jiàn),其消息風(fēng)暴擴(kuò)散系數(shù)非常之大。

同時(shí):

  • 需要存儲(chǔ)40條ack記錄;
  • 群數(shù)量,群友數(shù)量,群消息數(shù)量越來(lái)越多之后,存儲(chǔ)也會(huì)成為問(wèn)題。

是否有優(yōu)化方案呢?

1. 群消息的推送,能否改為接收方輪詢拉???

答:不能,消息接收,實(shí)時(shí)性是核心指標(biāo)。

2. 對(duì)于last_ack_msgid的修改,真的需要每個(gè)群消息都進(jìn)行ack么?

答:其實(shí)不需要,可以批量ack,累計(jì)收到N條群消息(例如10條),再向服務(wù)器發(fā)送一次last_ack_msgid的修改請(qǐng)求,同時(shí)修改這個(gè)請(qǐng)求之前所有請(qǐng)求的已讀回執(zhí),這樣就能將40個(gè)發(fā)送給服務(wù)端的ack請(qǐng)求量,降為原來(lái)的1/10。

3. 發(fā)送方在線時(shí),對(duì)于已讀回執(zhí)的發(fā)送,真的需要實(shí)時(shí)推送么?

答:其實(shí)不需要,發(fā)送方每發(fā)一條消息,會(huì)收到40個(gè)已讀回執(zhí),采用輪詢拉?。ɡ?分鐘一次,一個(gè)小時(shí)也就60個(gè)請(qǐng)求),可以大大降低請(qǐng)求量。

畫(huà)外音:或者直接放到應(yīng)用層keepalive請(qǐng)求里,做到0額外請(qǐng)求增加。

4. 會(huì)帶來(lái)什么副作用?

答:已讀回執(zhí)更新不實(shí)時(shí),最壞的情況下,1分鐘才更新回執(zhí)。當(dāng)然,可以根據(jù)性能與產(chǎn)品體驗(yàn)來(lái)折衷配置這個(gè)輪詢時(shí)間。

5. 如何降低數(shù)據(jù)量?

答:回執(zhí)數(shù)據(jù)不是核心數(shù)據(jù)。

  • 已讀的消息,可以進(jìn)行物理刪除,而不是標(biāo)記刪除;
  • 超過(guò)N長(zhǎng)時(shí)間的回執(zhí),歸檔或者刪除掉;

四、總結(jié)

對(duì)于群消息已讀回執(zhí),一般來(lái)說(shuō):

  • 如果發(fā)送方在線,會(huì)實(shí)時(shí)被推送已讀回執(zhí);
  • 如果發(fā)送方不在線,會(huì)在下次在線時(shí)拉取已讀回執(zhí);

如果要對(duì)進(jìn)行優(yōu)化,可以:

  • 接收方累計(jì)收到N條群消息再批量ack;
  • 發(fā)送方輪詢拉取已讀回執(zhí);
  • 物理刪除已讀回執(zhí)數(shù)據(jù),定時(shí)刪除或歸檔非核心歷史數(shù)據(jù);

消息發(fā)送推還是拉?

任何脫離業(yè)務(wù)的架構(gòu)設(shè)計(jì)都是耍流氓。

知其然,知其所以然。

思路比結(jié)論更重要。

責(zé)任編輯:趙寧寧 來(lái)源: 架構(gòu)師之路
相關(guān)推薦

2021-01-08 08:22:17

消息數(shù)據(jù)結(jié)構(gòu)開(kāi)發(fā)

2022-09-16 10:14:41

消息順序性分布式架構(gòu)

2019-08-30 14:58:47

JavaScript程序員編程語(yǔ)言

2017-01-23 13:08:46

大數(shù)據(jù)客戶畫(huà)像技術(shù)

2020-11-10 22:53:54

oracle數(shù)據(jù)庫(kù)

2020-12-08 05:41:46

人工智能人機(jī)融合機(jī)器學(xué)習(xí)

2020-02-28 16:10:13

攜號(hào)轉(zhuǎn)網(wǎng)運(yùn)營(yíng)商中國(guó)電信

2020-12-10 13:37:08

人工智能人機(jī)融合

2020-11-19 15:34:47

前端招聘開(kāi)發(fā)

2011-05-12 14:57:58

2022-06-12 23:36:26

微服務(wù)架構(gòu)單體應(yīng)用

2018-06-22 07:51:13

2012-11-27 10:36:19

公有云Azure數(shù)據(jù)中心

2019-01-10 09:11:51

消息順序性分布式服務(wù)端

2019-08-08 16:39:37

ERP信息化中小企業(yè)

2022-09-19 16:38:59

數(shù)據(jù)產(chǎn)品SaaSSnowflake

2022-06-10 14:13:43

數(shù)字化轉(zhuǎn)型企業(yè)IT中小企業(yè)

2018-08-16 08:03:21

Python語(yǔ)言解釋器

2013-03-04 10:10:36

WebKit瀏覽器

2022-06-02 08:03:19

PyCharmPython代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)