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

微信:我絕不丟離線消息!

開發
如果沒有打開手機,沒有登錄微信,好友發給我的微信消息,有沒有可能丟失呢?今天和大家聊聊離線消息的話題。

微信:我們絕不丟消息!》提到,單人實時聊天消息的可靠投遞,是通過應用層的超時、重傳、確認、去重來保證的。

那如果沒有打開手機,沒有登錄微信,好友發給我的微信消息,有沒有可能丟失呢?今天和大家聊聊離線消息的話題。

沒有做過IM業務的架構師可能會說,離線消息存儲數據庫不就行了嗎?可事實上,遠比你想的復雜。

接收方不在線,消息發送流程是怎么樣的?

如上圖所述,A給B發了一條消息,而B不在線,離線消息存儲的流程如下:

1. A發送消息給B,通過server中轉;

2. server查看用戶B的狀態為offline;

3. server將消息存儲到DB中;

4. server返回用戶A發送成功,并帶上特殊標識,避免A重發。

離線消息表如何設計?

很容易想到,消息業務有這樣的一些關鍵屬性:

t_offline_msg(
  receiver_uid,  // 離線消息接收方
  msg_id,  // 消息ID
  time,  // 消息發送時間
  sender_uid, // 消息發送方
  msg_type, // 消息類型
  msg_content, // 消息內容 
  …
);

B登陸之后,如何拉取A發給他的離線消息呢?

(receiver_uid(B), sender_uid(A))

在上述索引查詢,然后把離線消息刪除,再把消息返回B即可。

整體流程如上圖所述:

  • B拉取A發送給ta的離線消息;
  • server從DB中拉取離線消息;
  • server從DB中把離線消息刪除;
  • server返回給用戶B想要的離線消息;

想到這一步,也不難。

那么問題來了,B登錄微信的時候,不止要拉取A發給他的離線消息,還需要拉取所有其他好友發給他的離線消息,這該如何實現呢?

如果用戶B有很多好友,登錄后客戶端需要對所有好友進行離線消息拉取。

客戶端偽代碼:

get B's friend-list;  // 拉取B的好友列表
for(all uid in B's friend-list){    // 遍歷所有好友uid
         get_offline_msg(B,uid);   // 拉取離線消息
}

如果有10000個好友,難道要拉取10000次?

畫外音:我的微信好友已滿員,大家猜微信好友上限是多少?

有沒有減少拉取次數的優化方法呢?

按需拉?。合壤「鱾€好友的離線消息數量,真正查看離線消息時,才往服務器發送拉取請求。

除了減少流量的“按需拉取”優化,還有減少拉取次數的優化方案么?

一次性拉?。嚎梢砸淮涡酝ㄟ^receiver_uid即接收方ID,拉取所有好友發送給B的離線消息,把登錄時與服務器的交互次數降低為了1次。到客戶端本地再根據sender_uid進行計算。

問題又來了,用戶B一次性拉取所有好友發給ta的離線消息,消息量很大時,一個請求包很大,速度慢怎么辦?

分頁拉取:根據業務需求,先拉取最新的一頁消息,再按需一頁頁拉取。

新的問題又來了,離線消息會不會丟失,用戶會不會收不到呢?

例如,上述步驟第三步執行完畢之后(刪除了離線消息),第四個步驟離線消息返回給客戶端過程中,服務器掛掉,路由器丟消息,或者客戶端crash了,那離線消息豈不是丟了么。

畫外音:數據庫已刪除,用戶卻還沒看到。

如何保證離線消息的可達性?

加入ACK機制:如同在線消息的應用層ACK機制一樣,離線消息拉時,不能夠直接刪除數據庫中的離線消息,而必須等應用層的離線消息ACK,等客戶端真的收到離線消息,才能刪除數據庫中的離線消息。

新的問題又來了,如果用戶B拉取了一頁離線消息,卻在ACK之前crash了,下次登錄時會拉取到重復的離線消息么?

拉取了離線消息卻沒有ACK,服務器不會刪除之前的離線消息,故下次登錄時系統層面還會拉取到。和在線消息投遞一樣,接收方通過msgid去重,系統層面會收到重復消息,但在業務層面,用戶卻無感知。

另一個問題,假設有N頁離線消息,現在每個離線消息需要一個ACK,那么豈不是客戶端與服務器的交互次數又加倍了?有沒有優化空間?

其實,不用每一頁消息都ACK,在拉取第二頁消息時相當于第一頁消息的ACK,此時服務器再刪除第一頁的離線消息即可,最后一頁消息再ACK一次。這樣的效果是,不管拉取多少頁離線消息,只會多一個ACK請求,與服務器多一次交互。

稍作總結

離線消息的可靠投遞,關鍵技術有:

  • 對于同一個用戶B,一次性拉取所有用戶發給ta的離線消息,能大大減少服務器交互次數;
  • 按需拉取,是無線端的常見優化;
  • 分頁拉取,是一個請求次數與包大小的折衷;
  • 應用層的ACK,應用層的去重,才能保證離線消息的不丟不重;
  • 下一頁的拉取,同時作為上一頁的ACK,能夠極大減少與服務器的交互次數;

知其然,知其所以然。

思路比結論更重要。

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

2025-03-31 10:49:16

2016-11-02 13:12:31

微信離線消息

2016-10-11 16:31:56

微信服務器消息

2025-04-17 09:00:00

架構聊消息微信

2024-04-09 09:08:09

Kafka消息架構

2021-09-08 15:10:02

微信收費移動應用

2013-04-08 16:19:40

微信微信公眾平臺圖文消息

2019-08-21 07:44:32

離線消息拉取開發

2013-10-24 11:00:30

馬云微信

2024-12-19 10:00:00

Python發送消息編程

2021-09-07 08:26:07

微信微信收費騰訊

2018-05-23 09:11:42

微信Android開發面試

2013-08-08 10:13:25

微信

2022-09-12 18:29:49

kafka緩存數據

2015-06-04 09:26:23

微信推送模板PHP代碼

2014-09-24 11:32:21

微信企業號開發

2014-09-24 11:11:08

微信企業號開發

2021-03-15 20:55:33

微信刷單移動應用

2021-04-16 11:27:16

Python表情微信

2021-05-14 07:18:07

監控微信聊天
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九热精品视频在线观看 | 中文天堂在线一区 | 91免费在线视频 | 国产精品一区二区三区四区 | 久久精品视频播放 | 四色永久 | 国产精选一区 | 奇米av| av色站 | 日韩av在线中文字幕 | 免费成人在线网站 | 久久久综合色 | 亚洲成人免费视频 | 亚洲高清中文字幕 | 色资源在线视频 | 成人亚洲视频 | 91精品国产高清一区二区三区 | 日韩av电影院 | 中文字幕91av | 玖玖精品视频 | 欧美一级欧美一级在线播放 | 国产网站在线免费观看 | 成人高清视频在线观看 | 欧美一区视频 | 久久久久久国产精品久久 | 国产日韩欧美在线观看 | 午夜激情在线视频 | 玖操| 久久精品一区二区三区四区 | 黄网免费 | 国产一级片久久久 | 毛片久久久 | 国产男女猛烈无遮掩视频免费网站 | 国产乱码久久久久久 | 超碰97免费观看 | 亚洲在线中文字幕 | 麻豆国产一区二区三区四区 | 国产97在线看| www.788.com色淫免费 | 懂色中文一区二区三区在线视频 | 日韩精品亚洲专区在线观看 |