默认

IM消息送达保证机制实现(二):保证离线消息的可靠投递

查看数: 463555 | 评论数: 51 | 收藏 20
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2016-11-13 22:16

正文摘要:

1、前言 本文的上篇《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》中,我们讨论了在线实时消息的投递可以通过应用层的确认、发送方的超时重传、接收方的去重等手段来保证业务层面消息的不丢不重。 ...

评论

苏门答腊伟 发表于 3 个月前
服务端居然不存储消息吗?如果客户端卸载了软件,以前的消息其实是丢了?按道理无论在线还是离线都应该存消息的吧
JackJiang 发表于 11 个月前
引用:doublesouth 发表于 2023-06-09 12:42
如果每条消息在下发之前都存入离线消息库,是不是还得监听客户端ack,如果确认客户端收到消息了再从离线 ...

严谨来说,确实需要客户端ack的
doublesouth 发表于 11 个月前
引用:JackJiang 发表于 2023-06-08 21:20
通常肯定是先持久化存库再下方,不然必定会有意外发生

如果每条消息在下发之前都存入离线消息库,是不是还得监听客户端ack,如果确认客户端收到消息了再从离线库删除消息?
没有这个机制的话,离线消息库感觉存储的并不是都是离线消息,退化成存储了全量的消息。
921124136 发表于 11 个月前
我只是好奇,又查询又删除的,这数据库不会锁表吗?
JackJiang 发表于 11 个月前
引用:doublesouth 发表于 2023-06-08 19:49
关于“Step 2:服务器查看用户B的状态,发现B的状态为“offline”(即B当前不在线);”
当用户B在线,服 ...

通常肯定是先持久化存库再下方,不然必定会有意外发生
doublesouth 发表于 11 个月前
关于“Step 2:服务器查看用户B的状态,发现B的状态为“offline”(即B当前不在线);”
当用户B在线,服务端推送下行消息给B的时候失败了,导致B的客户端未收取到消息,消息也没有存入到离线消息库,这种情况会导致用户B的客户端丢失消息吧。
JackJiang 发表于 2 年前
引用:lmyJavaDE1 发表于 2018-08-07 17:02
"进一步优化,解决重复拉取离线消息的问题:拉取了离线消息却没有ACK,服务器不会删除之前的离线消息,故下 ...

客户端上次拉过后,本地有缓存,这次再拉到就根据缓存来去掉,缓存里有的就是表示上次已拉过
椎锋陷陈 发表于 2 年前
引用:某非著名程序 发表于 2021-02-05 09:24
文中第5条优化2一般一次性拉取,主流的的移动端IM(比如微信、手Q等)通常都是以“优化方案2”为主。然后第 ...

作者前后的描述其实并不矛盾,因为关注的重点不同。

前者主要涉及的是读扩散和写扩散的问题,
所谓读扩散,假设用户有500个好友,那就要执行500个HTTP请求,除了作者说的那些问题,还有
无效请求的问题,即某些好友并没有新增的离线消息。
所谓写扩散,就是有一个额外的「收件箱」,用于存储所有好友的离线消息,每次都要额外写入
一次,用户拉取所有离线消息只需要从这个收件箱拉取即可,拉取之后再在本地进行分组,可以
大大减少请求次数。

后者是在前者的基础上,考虑了离线消息比较多的情况,造成数据量很大,请求速度慢,本地频繁
存储后刷新引起卡顿,因此改成了分页拉取,减少每次拉取和要处理的数据量,边拉取边处理。
庞衍楠 发表于 2 年前
学习了
JackJiang 发表于 2 年前
引用:江明 发表于 2021-07-23 11:01
是否可以通过端上缓存最新的消息时间戳,拉取的时候带上时间戳向服务器请求,服务器返回>=时间戳的消息。
...

可行,这就是个比较优秀的方案
JackJiang 发表于 2 年前
引用:lmyJavaDE1 发表于 2018-08-07 17:02
"进一步优化,解决重复拉取离线消息的问题:拉取了离线消息却没有ACK,服务器不会删除之前的离线消息,故下 ...

这里的去重说的是客户端去重,因为你客户端没有ack,服务端就没法删除已拉取的,所以下次还能拉到,而你客户端本地有缓存,下次再拉的消息,用消息id跟本地的比,已经存在的就表示重复,不保存就行了
江明 发表于 2 年前
是否可以通过端上缓存最新的消息时间戳,拉取的时候带上时间戳向服务器请求,服务器返回>=时间戳的消息。

这样服务端只需一个表存储全量的消息即可。
而且对应多端的情况,也是同样的逻辑。

这样是否可行?
JackJiang 发表于 3 年前
引用:某非著名程序 发表于 2021-02-05 09:24
文中第5条优化2一般一次性拉取,主流的的移动端IM(比如微信、手Q等)通常都是以“优化方案2”为主。然后第 ...

微信是这个逻辑,但qq貌似有点差异
某非著名程序 发表于 3 年前
文中第5条优化2一般一次性拉取,主流的的移动端IM(比如微信、手Q等)通常都是以“优化方案2”为主。然后第6条提到又分页拉取,这个分页也是拉取所有好友的分页消息,然后点进会话再拉取对应的离线消息吗?
JackJiang 发表于 3 年前
引用:某非著名程序 发表于 2021-01-31 09:14
服务端不会存储消息,如果客户端切换设备,或者同时有多个端如PC端、手机端,是不是意味着没有历史记录

是的
某非著名程序 发表于 3 年前
服务端不会存储消息,如果客户端切换设备,或者同时有多个端如PC端、手机端,是不是意味着没有历史记录
JackJiang 发表于 4 年前
引用:ToFind1991 发表于 2020-04-01 18:00
你好,我有个疑问,就是最后说分页拉取的时候,后一次是前一次的ack,会不会出现拉20条消息,有一条丢了,这 ...

分布拉取一般都是通过http接口,要么全部成功,要么全部失败。
poiupoiu 发表于 4 年前
感谢分享
ToFind1991 发表于 4 年前
你好,我有个疑问,就是最后说分页拉取的时候,后一次是前一次的ack,会不会出现拉20条消息,有一条丢了,这个时候处于一种半完成的状态,是要单独把丢失的那条拿到然后再下一页吗?

返回顶部