目录

很多文章都已经是好几年前的百度、QQ、微信等大型 IM 当初设计方案与后续发展,虽然已经过去很多年,但对于如今中小型公司来说,都是宝贵的经验,借助宝贵的经验结合开源的 IM 项目文档来,减少踩坑,可以从更高层面结合自己的实际项目需求,从上而下完善个性化架构设计,指导项目 IM 模块的实现与优化。

百度公共 IM 系统的 Andriod 端 IM SDK 组件架构设计与技术实现

来源:百度公共 IM 系统的 Andriod 端 IM SDK 组件架构设计与技术实现

  • 业务层主要模块

    • 1)登录管理:负责在 IM SDK 初始化后长连接建连、重连,账号体系登录、退登、重登等情况下,IM 系统的登录、退登,登录信息、事件管理以及异常处理机制等;

    • 2)同步管理:负责在 IM 登录后同步单聊、群聊会话,消息、通知消息等账号内相关数据;

    • 3)配置管理:登录后负责管理用户在 IM 系统中相关全部配置项;

    • 4)通知管理:负责用户处于在线/离线状态时系统通知处理,包括但不限于通知监听、解析、指令调度分发等操作;

    • 5)消息管理:基于原始消息数据,提供消息发送、删除、更新、撤回、查询等操作;

    • 6)会话管理:负责基础会话数据管理以及会话创建、更新、删除、查询以及会话监听管理、变更分发等机制;

    • 7)群成员/好友管理:管理登录后会话中的一些联系人数据以及群成员信息;

    • 8)群管理:负责管理群消息、群操作(如拉人、踢人、退群、解散、禁言、增加管理员等操作);

  • 如何提升客户端和服务端性能?

    • 客户端登录后减少非必须请求,总未读数获取由从服务端获取,改为先使用客户端本地计算,同步数据后再更新。
    • versionCode 机制 + 消息拉取队列提升客户端和服务端性能。客户端提供的 versionCode 与服务器最新的 versionCode 一致,则说明无新数据。versionCode 还可以用于替代 ACK。
    • 所有会话消息获取建议同步队列,防止客户端线程池饱和风险,减少服务端并发请求。
  • 如何同账号同步消息操作到离线设备?

    用户操作数据化构造成指令消息,解决统一账号在线设备操作后,其他离线设备在线时用户数据一致性。比如已读操作。

  • 如何账号多端同步消息机制?

    服务端通知其他设备同步,其他设备主动拉取。也可以服务端直接推送到其他设备。

  • 如何获取新消息?

    推拉结合的方式获取新消息。下行消息走长连接方式,接收方离线时,服务器可能需要一个心跳周期才能感知到,推送+ACK 方式(或 versionCode)是否会更节省请求和流量?

  • 如何保证消息可靠投递?

    顺序性与完整性考虑,确保消息不丢失不重复。

    消息数据链路:

    • 1)消息协议组装;
    • 2)长连接通道发消息;
    • 3)服务端接收到消息;
    • 4)服务端保存消息;
    • 5)服务端通过长连接下行通知消息;
    • 6)接收方根据通知拉取消息。

    想要保证实时&离线消息的可靠投递,需要对收发消息的整条链路各阶段增加从产品交互到技术方案上增加兜底和容错处理。确保链路上每个环节的成功率。

快速裂变:见证微信强大后台架构从 0 到 1 的演进历程(一)

来源:快速裂变:见证微信强大后台架构从 0 到 1 的演进历程(一)

  1. 消息数据同步到客户端,消息数据版本号,减少不必要的 ACK 确认请求。类似百度公共 IM 中提到的 versionCode 优化。
  2. 业务数据监控补齐。
  3. 由于群成员少,群聊采用写扩散方式。
  4. KVSvr 高性能存储。

快速裂变:见证微信强大后台架构从 0 到 1 的演进历程(二)

来源:快速裂变:见证微信强大后台架构从 0 到 1 的演进历程(二)

  1. 平台化来自一个具体点的扩散而来。
  2. 国内海外 master-master 对用户集合进行切分的存储架构。
  3. 漫游,数据中心会引导用户重新连回归属数据中心。
  4. 海外数据中心数据同步回国内数据中心的延迟是可理解的,问题不大。
  5. 账号的全局唯一性。
  6. 多园区物理隔离异地容灾。
  7. 先抗住再优化。
  8. 支持协程异步化,单实例上百并发提升到上千并发。
  9. 防止扩散雪崩,通过过载拒绝请求的方式,保证过载时能正常提供服务。
  10. 安全隐私。引入票据概念,访问用户核心数据,要求验证票据,票据在用户登录后由服务器颁发。
  11. PhxSQL。支持完整 MySQL 功能,又同时具备强一致性、高可用和高性能的 SQL 存储
  12. 资源调度系统(Yard)可以把机器资源的分配和服务的部署自动化。

IM 单聊和群聊中的在线状态同步应该用“推”还是“拉”?

来源:IM 单聊和群聊中的在线状态同步应该用“推”还是“拉”?

  • 好友在线状态更新,推送方式实时,但会导致消息风暴。

    设一个 im 系统平均每个用户有 200 个反向好友,平均有 20% 的反向好友在线,那么消息风暴扩散系数 N=40,这意味着,任何一个状态的变化会变成 40 个推送请求。

  • 群友状态一般采用拉取的方式获得,因为群友状态的消息风暴系数一般比较大,全部实时获取,系统往往承受不住。

  • 按需拉取与延时拉取是常见的做法,既满足用户,也降低服务器压力。

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的 (图片压缩篇)

来源:腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的 (图片压缩篇)

  • 用 Google 的 WebP 格式用户上传的原图进行后台压缩。

    JPEG、PNG 和 GIF 动图三中主流格式,WebP 不支持 gif 压缩。

    在保障同等质量下的 WebP 图片比原图体积小 30%。

  • 腾讯自研 TPG 图片压缩格式格式

    流量分析发现仅有 5% 下载次数的 GIF 格式图片占用了 20% 带宽。

    经在 QQ 相册验证 TPG 可在同等质量下可将 GIF 大小降低 90%,将 WebP 再降低 21%,比 JPEG 节约 43% 左右。并做了编解码性能的优化,耗时等都优于 WebP。为此 17 年全面推广相册 TPG 格式化。

    局限:客户端需要具备解码 SDK 才能正常使用。

  • 全类型多场景图片压缩解决方案。

    HEIF 是 H.265 标准的建议格式,比 JPEG 小 40%,苹果 iPhone7 升级 IOS 11 以上拍摄直接生成的是 HEIF 格式,同等质量文件大小和 TPG 差不多。

    如果两个 iPhone7(IOS11)用户互发本机拍摄的图片(HEIF 格式),则无需转码可比原 JPEG 图节约 40% 以上的流量和存储,在其他不支持的客户端下载时需转码为其他格式。所以针对部分苹果用户体验更好,要成为主流还有待普及。

腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的 (音视频技术篇)

来源:腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的 (音视频技术篇)

  • 存在冗余下载问题。

    限制下载,永远只比播放多 20 秒(经过持续验证,具体情况具体分析,卡顿率在 2%),用户网速差,发生二次缓冲时,将不限速。

  • 长视频边下边播,不播放即停止下载。

    大大降低用户平均等待时间,以及降低冗余下载。

  • 限制大文件转发次数。

    大于 1G 以上的文件,通常是盗版电影,不希望传播,所以限制大文件转发次数。

  • H.265 的硬解码与软解码,支持云适配动态下发最适合的码率。

    小孩子说的刚刚好就是最好的。

  • 总结:文件压缩的更小,下载次数少,冗余下载少,质量不变。

微信团队分享:iOS 版微信是如何防止特殊字符导致的炸群、APP 崩溃的?

来源:微信团队分享:iOS 版微信是如何防止特殊字符导致的炸群、APP 崩溃的?

  • 微信团队为了用户体验,优化了大家都觉得很正常的文字排版展示,界面改动虽小,研究与花的力气可不少,效果却也很明显。

微信团队分享:iOS 版微信是如何防止特殊字符导致的炸群、APP 崩溃的?

让互联网更快:新一代 QUIC 协议在腾讯的技术实践分享

来源:让互联网更快:新一代 QUIC 协议在腾讯的技术实践分享 - 网络编程/专项技术区 - 即时通讯开发者社区!

quic 协议的普及任重道远,会遇到以下挑战:

1)小地方,路由封杀 UDP 443 端口(这正是 QUIC 部署的端口); 2)UDP 包过多,由于 QS 限定,会被服务商误认为是攻击,UDP 包被丢弃; 3)无论是路由器还是防火墙目前对 QUIC 都还没有做好准备。

iOS 后台唤醒实战:微信收款到账语音提醒技术总结

来源:iOS 后台唤醒实战:微信收款到账语音提醒技术总结 - 其它分享/专项技术区 - 即时通讯开发者社区!

  • iOS APNS 支持后台唤醒 APP。1、silent notification,允许唤醒 30s 的后台运行时间,但每小时的次数有限。2、VoIP Push notification 具有更高优先级、低延迟的优势,并且没有次数限制。
  • 播放空白音频曲线救国检查设备是否开启静音。
  • 设置声音阈值,触发事件时调节到阈值,结束后声音调回原音量。

移动端 IM 实践:WhatsApp、Line、微信的心跳策略分析

来源:移动端 IM 实践:WhatsApp、Line、微信的心跳策略分析-IM 开发/专项技术区 - 即时通讯开发者社区!

注:GCM 已经升级为 FCM。

WhatsApp Line GCM
WIFI 4 分 45 秒 3 分 20 秒
手机网络 4 分 45 秒 7 分钟

1、Line、WhatsApp、微信消息推送策略的优点。

  • a)微信:当前心跳间隔比竞品,所以微信在新消息提醒上会最及时。(付出代价有哪些呢?)
  • b)使用 GCM:Line 和 WhatsApp 使用 GCM 策略的最大优点就是省电,以及减轻系统负荷(减少后台应用数目)。因为使用的系统自带的长连接,不需要额外自己维护长连接。
  • c)Line:Line 的轮询策略,优点是当 Line 处于活跃状态时,及时收消息。当 Line 处于不活跃状态时,省电。主动拉取。

2、Line、WhatsApp 微信消息推送策略的不足。

  • a)微信当前心跳频率相对竞品较大,在耗电耗流量占用信令通道等方面有所影响。
  • b)Line 的轮询策略,导致的问题是消息可能会延迟接收,测试发现最大延迟间隔到 2.5 小时。活跃与不活跃临界点时模糊的,所以可能因为不活跃导致延迟主动拉取消息,使得消息延迟。
  • c)WhatsApp 和 Line 使用 Push 拉起一个定时长连接策略,缺点是要依赖 Google 的 Push 服务,如果 Google 的 Push 服务不稳定,消息也会延迟接收。国内 FCM 是不稳定的。
  • d)在国内的移动和联通 2G 网络下,由于运营商的策略,GCM 长连接频繁断连,WhatsApp 的 Push 消息很不及时,体验非常差。

微信后台团队:微信后台异步消息队列的优化升级实践分享

来源:微信后台团队:微信后台异步消息队列的优化升级实践分享

  • MQ 调度管理

  • MQ worker

  • 跨机消费模式解决局部积压问题。

  • MQ 调度管理广播自己的积压情况给所有 worker。worker 格局自己的状态选择是否帮助消费。

  • 批量并行化投递。类 map reduce 任务处理框架。

    通俗理解 map reduce

  • MQ 过载保护,自适应调整动态限速。

腾讯原创分享 (一):如何大幅提升移动网络下手机 QQ 的图片传输速度和成功率

来源:腾讯原创分享 (一):如何大幅提升移动网络下手机 QQ 的图片传输速度和成功率 - 网络编程/专项技术区 - 即时通讯开发者社区!

  • 必须分小片上传一个文件。文件大小接近 0 则传输成功率接近 100%,反之文件大小无穷大,传输过程必然失败。且大文件上传失败重传给用户的时间、空间流量上的体验非常不友好。
  • 不同网络类型的分片初始大小各有不同。
  • 应该尽可能的动态增大分片大小,如后一片是前一片的 N 倍数,以减少分片数量。确保大部分优质网络下带宽利用率,提高传输速度。
  • 并实时关注网络类型的变化,及时变更动态分片策略。
  • 分片一旦传输失败,重试时采用初始分片大小重新上传。提高重传成功率。
  • 每个分片都有一定次数的失败机会,当一个分片的所有重传都失败了,才定义为图片上传失败。
  • 支持断点续传。

以上方案可以解决或减少:失败率高、流量浪费多等问题。

继续优化,有 5 个疑问:

  • 1、是否支持 http 的 keep-alive,使得后续的分片上传都可以使用前一次上传创建的 tcp 连接?

    经过成百上千次实验,得到结论:不仅一张图片的分片可以复用第一分片建立的 TCP 连接,有的时候时间间隔稍短的下一张图片甚至也可以复用上一张图片的连接。这样就不必担心分片会带来的巨大网络开销。

  • 2、动态分片大小,是否有最大分片大小约束,避免传输失败率越来越大?

    TODO

  • 3、分片提高了上传成功率与降低了重传的耗时,但却引入了额外的开始,必然导致传输速度低于单文件上传,会否有办法降低下降幅度?

  • 4、单个分片上传失败的主要原因会是什么?提升单次的成功率来提升整体的成功率。

  • 5、重传策略靠谱吗?依据是什么?如果重传成功率低,反而带来新的浪费?

现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

来源:现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

  • 采用 httpdns 实现 ip 直连,避免 dns 解析慢、被运营商劫持问题。

  • 支持 http2。iOS 9 以上原生支持 http2,安卓开源网络库 okhttp3 以上版本支持 http2。

    http 1.1 开始支持 keep-alive,即复用连接,但不能并行,也就是下一个请求要复用连接,需要等连接中的当前请求响应结束。

    http 2 开始支持多路复用的连接,也就是支持多个请求同时复用同一个连接,通过 stream 标识不同请求,方便连接识别不同请求,并组装对应数据。

    QUIC 解决了 HTTP2 的多路复用让所有请求都在同一条连接进行,中间有一个包丢失,就会阻塞等待重传,所有请求也就被阻塞了 的问题。

DNS 优化


9ong@TsingChan 2024 markdown