IM 系统消息丢失问题排查反思
引子
今年各种闹水灾,河南闹了山西闹。面对水灾除了内心对灾区的祝福,还对一个词有了思考---流量。
流量本来是指单位时间内流经封闭管道或明渠有效截面的流体量,本来是形容水的,现在在我们技术领域主要指我们服务的访问量。我们面对小雨的心情可能会很欣喜,但是但流量大到一定程度时,我们就不得不保持敬畏之心了。但线上流量增长迅速时,我们不得不小心应对。想起前两天遇到的 IM 的一个消息不显示的问题。
背景
首先声明,整个我们整个 IM 系统的架构设计上是不存在丢消息的,但是为什么会遇到消息不展示的情况呢?
先介绍一个背景,就是 IM 对消息的存储分为两层,一层是数据库 DB 的存储,还有一层内存热数据的存储,我们为每个用户分配了一块固定消息条数(比如 800 调)的内存消息队列,。客户端在初始化时可以通过拉取热数据消息队列,同时依据热数据消息队列生成用于展示的对话列表。对于历史老的消息,通过另一个接口,在进入具体会话时从 DB 拉取当前会话的历史消息。
问题
这里面就出现问题了,平时我们测试遇不到,但是在真实的海量用户场景下,会有这么一种 case:
用户某个会话有 100 条消息,其中 10 条为热数据在缓存中。
用户首次安装应用后拉取了热消息数据,当前会话最新的消息序列是 90 到到 100;
又有新的消息 100 到 110,用户一段时间未登陆,未拉取下来,但是服务端因为缓存大小限制导致 100 到 110 只存在了数据库,此时 100 到 110 无法从内存缓存接口获取,当进入会话时,逻辑上只会拉 90 之前的消息,导致 100 到 110 之间产生消息空洞。
总结
这种问题日常测试场景不会遇到,但是用户量上来,流量上来,各种场景 case 就会发生,就会命中这种 bug,此时只能通过卸载重装来解决。所以我们在设计架构和代码逻辑时一定要尽最大可能思考全面,覆盖尽可能多的场景。
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/5545ef39834d0a2be70f5f963】。文章转载请联系作者。
评论