当前位置: 首页 > news >正文

架构师面试(三十一):IM 消息收发逻辑

问题

今天聊一下 IM 系统最核心的业务逻辑。

在上一篇短文《架构师面试(三十):IM 分层架构》中详细分析过,IM 水平分层架构包括:【入口网关层】、【业务逻辑层】、【路由层】和【数据访问层】;除此之外,还有最前端的【终端层】和 最底层的【存储层】。

在这样的架构约束下,完整的消息收发逻辑流程应该如何设计呢? 消息的收发逻辑应当具备可靠性和及时性!

解析

IM 消息的收发需要具备 “可靠性” 和 “及时性”;

“可靠性 ” 一方面要求消息不能丢失,另一方面要求如果接收方在线就应该收到消息,如果不在线就需要通过其他触达通道通知到;“及时性” 要求消息的收发需要低延时。

基于水平分层架构,IM系统完整的消息收发逻辑流程划分为三个阶段,即:生产消息阶段、推送消息阶段 和 消息确认阶段;另外为了保证消息的“可靠性”设计三重保障。整个消息收发逻辑流程如下图所示:

图片

以终端APP(uid = 101)发消息给终端APP(uid = 102)为例说明:

(1)生产消息阶段

终端 APP(uid = 101)基于与 Entry 之间的长连接发送消息到 Entry,因为 Entry 不负责具体的业务逻辑,所以 Entry 会基于与 Logic 之间的 RPC ,将消息请求直接转发到 Logic进行处理(Entry 是如何寻址到 Logic 的,我们会在后面的技术短文中讲解)。

Logic 接收请求后,首先调用 Spam 服务进行风控过滤,然后 Logic 通过 RPC 调用 Das,由 Das 分别写 “消息库”和“联系人库(IM 的消息库和联系人库应该如何设计?我们仍会在后面的技术短文中讲解^-^);写库成功之后,由 Logic 发送 response 到 Entry,由 Entry 转发 response 到 终端APP。(大家可以思考一下,如果终端 APP 没有收到 response 会怎样?)

在生产消息阶段需要重点理解和掌握的是:IM 服务端接收到消息后,是先落库再回复,顺序不能乱了;就好像我们去银行柜台存钱时,业务员一定是先收钱再记账,这个不能错了!

生产消息阶段描述的是消息的生产方和 IM 服务端之间的事情;接下来就是 IM 服务端和消息接收方之间的交互了。

(2)推送消息阶段

Logic 首先访问 Router,获取消息接收方(uid = 102)的在线状态和所连接的 Entry;如果用户uid = 102离线,则 Logic 封装一条 MQ 消息发送到 MQ,由下游的 Extlogic 进行离线用户的消息触达逻辑(包括 推送手机PUSH、推送微信公众号消息、推送 SMS 短信消息、推送 VOIP 等),保证能通过这些通道触达到用户;如果用户uid = 102在线,则 Logic 访问 Router 中缓存的数据,寻址到 Entry 地址,然后 Logic 基于与 Entry之间的 RPC 连接,将消息推送到 Entry(注意:这里的 RPC 与 第一阶段中 Entry 调用  Logic时的 RPC 是两条不同的连接哈!想一下为什么呢?)。

Entry 与 Router 之间有可能数据不一致,即 Router 中缓存的用户uid=102是在线状态,但 Entry 记录uid=102已经离线,这就是典型的IM的【假在线】问题(在后面的技术短文中,我们会详细讲解^-^);如果 Entry 记录用户uid=102离线,则会回调 Logic 的 unreachable 接口,此时Logic 会通过 MQ 通知 Extlogic 走离线用户的消息触达逻辑;如果 Entry 记录用户uid=102在线,则会通过与终端之间的长连接,将消息推送出去。

在推送消息阶段需要重点理解和掌握的是:通过 Router 和 Entry 过滤后,会筛选出【假在线】用户,对于假在线用户,需要通过“离线用户的消息触达逻辑”来触达他们!

是不是通过 Router 和 Entry 过滤后,就可以筛选出所有的“假在线”用户呢?肯定不是的!上面说过为了保证消息的可靠性,设计了三重保障,Router 和 Entry就是第一重保障和第二重保障,第三重保障就是消息处理的第三阶段!

(3)消息确认阶段

Entry 将消息推送给消息接收方之后,消息接收方需要回复 ACK 到IM服务端进行确认;Logic 在一定时间内(比如15秒),如果没有收到消息接收方回复的 ACK,仍然需要通过 MQ 通知下游的 Extlogic 走离线用户的消息触达逻辑。

Logic 针对每一条推送出去的消息都会开启一个倒计时(比如15秒),在消息的吞吐量比较小的时候(比如每秒钟不到10条),我们可以为每条消息都开启一个线程来做专门的业务处理;如果消息的吞吐量比较大的时候(比如每秒钟5000条),又该如何处理呢?这是一个非常典型的业务场景,大家可以思考一下,在后续的技术短文中会陆续讲解。

完整的IM消息逻辑处理流程,在面试时是否可以一气呵成呢?

http://www.xdnf.cn/news/7489.html

相关文章:

  • 手撕STL——vector
  • 利用DeepSeek设计一个HTML批量转换工具设计
  • Hadoop的三大结构及其作用?
  • hadoop的三大结构及各自的作用
  • yarn的定义
  • 「数据可视化 D3系列」入门第九章:交互式操作详解
  • 自动驾驶与机器人算法学习
  • 【区块链通用服务平台及组件】京北方分布式身份管理平台 | FISCO BCOS 应用案例
  • java八股之并发编程
  • 医院数据中心智能化数据上报与调数机制设计
  • 仿腾讯会议项目开发——界面关闭功能实现
  • Flink介绍——实时计算核心论文之Kafka论文详解
  • java输出、输入语句
  • Vue3 Composition API与十大组件开发案例详解
  • 杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其四
  • 【datawhaleAI春训营第一期笔记】AI+航空安全
  • Tensorflow实现用接口调用模型训练和停止训练功能
  • Mac mini 安装mysql数据库以及出现的一些问题的解决方案
  • 【前端HTML生成二维码——MQ】
  • uni-app 安卓10以上上传原图解决方案
  • 基于FPGA的AES加解密系统verilog实现,包含testbench和开发板硬件测试
  • 4.Rust+Axum Tower 中间件实战:从集成到自定义
  • 【Leetcode 每日一题】2364. 统计坏数对的数目
  • 再读bert(Bidirectional Encoder Representations from Transformers)
  • 学习设计模式《二》——外观模式
  • 京东物流基于Flink StarRocks的湖仓建设实践
  • UI 在教育产品涉及的领域
  • 如何评价2025 mathorcup妈妈杯数学建模竞赛?完整建模过程+完整代码论文全解全析来了
  • 2025年MathorCup数学应用挑战赛D题问题一求解与整体思路分析
  • Android 12.0 framework实现对系统语言切换的功能实现