测试的文档

admin 更新于 2026-07-06 15:57

UniApp 自研 IM 天花板级完整方案(零掉线、低延迟、推送秒达、消息不丢)

整套体系分UniApp 客户端核心层、WebSocket 网关服务端、离线推送兜底、消息可靠一致性、弱网 / 后台保活、集群高并发六大模块,全部为生产级标准,对标大厂 IM 底层逻辑。

一、整体架构总览(延迟 P99<80ms,断连自愈 99.9%)

1. 技术栈选型(uniApp 最优组合)

客户端(UniApp)

  • 长连接:uni.connectSocket 单例全局 WS 管理器(杜绝多连接冲突)
  • 本地持久化:App 端uni-sqlite,小程序uni.storage分级缓存
  • 推送底座:uniPush2.0(聚合全厂商通道,离线必达)
  • 状态管理:Pinia/Vuex 全局统一连接状态、消息队列、会话偏移量 seq
  • 定时器:链式 setTimeout 心跳(规避系统休眠清空 interval)

服务端(三选一高性能网关)

  1. Go+Gnet/Gev(首选,百万连接,延迟最低)
  2. Java Netty(生态成熟,企业稳定)
  3. PHP Workerman(低成本,中小日活)

中间件(缺一不可)

  • Redis Cluster:在线用户映射、seq 序列号、心跳状态、离线消息缓存
  • MQ(Kafka/RabbitMQ):群聊扇出削峰、消息异步落库
  • MySQL 分表:聊天记录冷热分离,按用户 ID 哈希分表
  • Nginx 负载均衡:WS 集群分流、wss 加密、断线节点自动剔除

二、UniApp 客户端:彻底解决掉线、延迟、消息丢失(核心代码逻辑)

模块 1:全局单例 WS 连接管理器(杜绝多实例、重复连接)

1)精准心跳保活(解决假死、运营商断 TCP)

  • 前台:30s 发ping,服务端 5s 内返回pong
  • 后台 / 锁屏:缩短至 15s 心跳,防止运营商 60s 空闲断流
  • 超时判定:2 次无 pong = 判定断线,立即触发重连
  • 禁用 interval,使用递归 setTimeout,iOS / 安卓后台不被系统冻结定时器

2)指数退避断线重连(不雪崩、弱网快速恢复)

重连阶梯:1s → 2s → 4s → 8s → 15s(上限 15s,最大重试 10 次)
触发重连场景:
  • ws onClose/onError
  • ping 心跳超时无 pong
  • App.onShow 切前台检测连接断开
  • uni.onNetworkStatusChange 网络恢复自动重连
    区分主动登出异常断开:主动登出标记isManualClose=true,永久不重连

3)双通道冗余(在线实时 + 离线推送兜底,保证接收即时)

  1. 前台活跃:WS 长连接实时推送,毫秒级接收
  2. 后台 / 锁屏 / 进程被杀:uniPush 厂商通道透传通知,点击 App 自动同步离线消息
  3. 网络波动断线:重连后增量拉取缺失消息,无空白会话

模块 2:消息可靠投递(不丢、不乱序、去重)

  1. 全局唯一 msgId:客户端 UUID 生成,每条消息携带,服务端 Redis 去重 5 分钟,本地 Set 过滤重复消息
  2. ACK 确认机制
    • 发送消息存入本地待发缓存
    • 收到服务端ack:{msgId}才删除缓存
    • 5s 未收到 ack 自动重发,最多 3 次,防止网络丢包
  3. 会话递增 seq 序列号(核心防乱序)
    同一私聊 / 群聊服务端生成严格递增 seq,客户端本地记录每个会话最大lastSeq
    • 重连时上报lastSeq,服务端仅下发seq>lastSeq增量消息,无需拉全量历史
    • 收到消息按 seq 排序后再渲染 UI,彻底解决弱网消息倒序
  4. 本地 SQLite 持久化:消息落地本地数据库,杀进程重启不丢失聊天记录

模块 3:UniApp 多端专属兼容坑(解决各端莫名掉线)

  1. 微信小程序:切后台自动断 WS,依赖 uniPush 兜底,onShow 强制重连
  2. iOS App:后台限制网络,开启 Background Modes 远程推送,心跳缩短至 15s
  3. 安卓厂商(小米 / OPPO/vivo/ 华为):系统省电策略杀后台进程,必须完整配置厂商推送通道,否则离线完全收不到消息DCloud
  4. H5 端:wss 强制加密,HTTP 域自动降级长轮询兜底

三、离线推送整套方案(推送及时,关闭 APP 也秒收到)

1. 强制使用 uniPush2.0(uniApp 原生天花板推送)

三层推送路由自动切换,无需手动判断:
  1. App 前台在线:WS 直推(0 延迟)
  2. App 后台存活:个推长连接透传
  3. App 进程杀死:自动切换厂商系统通道(APNs / 小米 / 华为 / OPPO/VIVO)

2. 必做配置(缺一项推送直接失效)

  1. iOS:上传 APNs 生产证书,开启后台远程通知
  2. Android:逐个申请五大厂商推送密钥,填入 manifest
  3. App 打包必须云打包,本地基座不支持厂商离线通道
  4. 引导用户开启通知权限、关闭电池优化、允许后台弹出界面(安卓机型必引导)

3. 推送联动 IM 同步逻辑

  1. 推送透传携带fromUid/groupId、lastSeq
  2. 用户点击通知唤醒 App,自动执行增量同步接口,补齐断线期间所有消息
  3. 推送通知未读计数与本地会话未读数实时对齐

四、服务端网关:低延迟、百万连接、永不雪崩(不掉线根源)

1. WS 网关集群分层(水平扩容,单点故障不影响全量用户)

  1. 接入层 Nginx:wss 负载均衡,健康检查剔除宕机网关节点
  2. 网关层(Netty/Gnet):只处理 TCP 连接、ping/pong 心跳、消息转发,无业务逻辑,单机支撑 5 万 + 长连接
  3. 逻辑层微服务:消息分发、群聊扇出、离线消息存储、seq 生成
  4. 存储层:Redis 集群 + MySQL 分表 + MQ 削峰

2. 在线用户路由(解决跨网关消息收不到)

  • 用户登录网关时,Redis 存储uid -> gateway节点ID映射
  • 发消息时先查 Redis 目标用户在线网关,精准转发;不在线存入离线消息队列
  • 集群任意节点互通,用户切换网关自动更新映射,无消息丢失

3. 离线消息持久化(断网几天上线消息完整同步)

  1. 用户离线消息存入 Redis 临时缓存(7 天过期),同时异步落库 MySQL
  2. 上线携带本地 lastSeq,服务端查询区间消息批量下发,分页拉取避免一次性加载上万条卡顿
  3. 消息已读 ACK 同步更新 Redis 与数据库,防止重复推送

4. 群聊高性能扇出(千人群无延迟)

采用写扩散 + MQ 异步:单条群消息投递至 MQ,多消费线程并行推送给在线用户,避免同步循环阻塞网关,P99 延迟控制在 100ms 内

五、弱网 / 移动网络专项优化(4G / 电梯 / 地下室不断连)

  1. 心跳自适应:WiFi 30s,4G/5G / 弱网自动切 15s
  2. 消息分片:大于 2KB 图片 / 文件分片传输,单包不超过 1KB,弱网不易丢包
  3. 网络状态监听:uni.onNetworkStatusChange,断网标记缓存消息,网络恢复批量补发
  4. TCP 保活参数:服务端网关开启 TCP Keepalive,内核层探测死连接,快速回收无效连接

六、全链路监控(提前预判掉线、延迟故障)

  1. 客户端埋点:连接断开次数、重连耗时、消息往返延迟、推送到达率
  2. 服务端监控:网关连接数、消息 TPS、Redis 延迟、MQ 堆积量
  3. 告警规则:单节点掉线、推送到达率低于 95%、消息延迟 > 200ms 自动告警

七、天花板级标准指标(对标商用 IM)

  1. 消息端到端延迟:前台在线 P99 < 80ms
  2. 断线自愈恢复:网络恢复 3s 内重连完成
  3. 消息丢失率:0(ACK+seq + 离线缓存三重保障)
  4. 离线推送到达率:App 98% 以上(完整厂商通道配置)
  5. 单机网关承载:5 万并发长连接,集群无上限扩容
  6. 弱网 4G 环境:99% 连接稳定,无无故断连

八、避坑致命要点(自研 IM90% 失败都踩这些)

  1. 不要多页面创建多个 WS 实例,必须全局单例
  2. 不要只用 interval 做心跳,iOS 后台会冻结定时器
  3. 安卓不配置厂商推送,锁屏杀进程完全收不到消息
  4. 不做 seq 增量同步,每次上线拉全量历史,卡顿 + 消息重复
  5. 服务端不做集群用户路由,跨网关用户收不到消息
  6. 无 ACK 消息确认,弱网发送消息直接丢失无重试
  7. 只用 WebSocket 单一通道,后台断连无推送兜底

九、最简落地实施顺序

  1. 先封装 UniApp 全局 WS 管理器(心跳 + 重连 + ACK+seq)
  2. 部署高性能 WS 网关(Go/Netty)+Redis 集群
  3. 对接 uniPush2.0,完整配置全厂商推送证书
  4. 实现离线消息增量同步、本地 SQLite 持久化
  5. 网关集群负载均衡、MQ 削峰,支持高并发
  6. 全机型弱网、后台、杀进程全场景压力测试