🧩 典型题干
设计一个聊天系统:
- 支持实时消息推送
- 离线消息同步
- 消息有序
- 多端同步
📚 学习正文:IM 系统如何做到实时又可靠?
交互图:IM 关键链路闭环(点步骤看可靠性与一致性落点)
面试表达建议:连接是入口(长连接网关+路由表) → 消息先落库(msgId/seq) → 推送是优化体验(在线投递) → 拉取保证一致(离线增量) → ACK/重试保证不丢。
1) 建联与路由:长连接不要挂在业务服务上
- 连接网关:WebSocket/TCP 长连接集中由网关维护,业务服务无状态可水平扩展。
- 路由表:维护 userId -> gatewayNode/connId(Redis/注册中心/本地缓存+订阅)。
- 保活与迁移:心跳超时清理路由;断线重连会更新路由。
2) 发消息入口:鉴权/限流/幂等
- 鉴权:token + 会话成员校验(你是否在该会话里)。
- 限流:防刷/防抖(用户维度、会话维度)。
- 幂等:客户端请求带 clientMsgId,服务端返回 msgId;重试不生成多条消息。
3) 先落库再投递:可靠性的根
- msgId:服务端生成全局唯一(雪花/号段),用于去重与追踪。
- seq:会话内递增序号(单聊/群聊各一条序列),用于有序与增量拉取。
- 持久化:写消息存储后再触发投递(直接投递/或发 MQ 事件)。
4) 在线投递:把消息推到正确的网关
- 路由推送:根据路由表找到接收方网关节点并投递。
- 多端:同一 userId 可能绑定多个 connId,推送给所有在线端。
- 群聊扇出:可采用小群写扩散,大群读扩散/分层推送。
5) ACK 与重试:保证“不丢”与“不重复展示”
- 至少一次:服务端投递后等待 ACK,超时重试。
- 去重:客户端按 msgId 去重,避免“重试导致重复展示”。
- 投递状态:可维护已送达/已读回执(读扩散场景也要同步回执)。
6) 离线与多端同步:拉取增量保证最终一致
- 离线拉取:客户端携带 lastSeq 拉取增量,缺失消息补齐。
- 游标:每端维护游标或统一游标(看产品需求:各端阅读进度是否一致)。
- 关键表达:推送是体验优化,真正兜底一致的是“按 seq 拉取”。
7) 群聊扩展:写扩散 vs 读扩散
- 写扩散:写入每个成员 inbox,读快写重(适合小群)。
- 读扩散:群消息写一次,读时按成员拉取,写轻读重(适合大群)。
- 混合:小群写扩散,大群读扩散 + 在线端分层推送。
1) 需求澄清与量级
- 用户规模:在线用户数、日活用户数、并发会话数。
- 消息量级:每秒消息数、峰值消息数、消息大小限制。
- 功能范围:单聊/群聊/消息类型(文本/图片/文件)。
- 一致性要求:消息是否要求严格有序?允许短暂延迟吗?
2) 核心挑战
实时推送:长连接管理、心跳保活、断线重连
消息有序:单会话内消息严格递增
离线同步:用户上线后拉取离线消息
多端同步:手机/PC/Web 端消息一致
3) 数据模型设计
- 消息表:message(消息ID、会话ID、发送者、内容、时间戳、序列号)。
- 会话表:conversation(会话ID、类型、参与者、最后消息时间)。
- 用户会话:user_conversation(用户ID、会话ID、最后阅读位置)。
4) 消息投递架构
1) 发送者发消息到 API 网关
2) 消息服务持久化到 DB
3) 推送服务实时推送给在线用户
4) 离线用户消息存储到离线表
5) 用户上线时同步离线消息
系统架构图(面试时用它讲全链路)
客户端(App/Web/PC)
|
v
连接网关(WebSocket/TCP)集群
- 心跳保活 / 断线重连
- 连接鉴权
- 维护 userId -> connId
|
+--> 路由表(Redis/注册中心): userId -> gatewayNode
|
v
消息接入服务(API)
- 鉴权/限流/幂等(clientMsgId)
- 生成 msgId / 会话 seq
|
+--> 消息存储(DB/分区表/冷热分层)
|
+--> MQ(可选):投递事件/回执事件/离线补偿
|
v
投递/推送服务
- 查路由 -> 投递到目标网关
- 在线投递、多端同步
- 群聊扇出(写扩散/读扩散)
|
v
客户端 ACK/回执
- 投递 ACK(至少一次 + 去重)
- 已读回执同步(多端)
离线与一致性:客户端按 lastSeq 拉取增量兜底;超时重试/对账补偿修复异常
5) 实时推送实现
- 长连接:WebSocket/TCP 长连接,支持心跳和重连。
- 连接管理:用户-连接映射,支持多设备同时在线。
- 消息路由:按用户ID路由到具体连接,支持集群扩展。
6) 可靠性保障
消息去重:基于消息ID的客户端去重
离线同步:可靠的离线消息存储和拉取
多端同步:基于序列号的消息同步机制
监控告警:消息延迟、推送失败率监控