不畏移山,手机QQ技术架构升级变迁史

共 6902字,需浏览 14分钟

 ·

2024-05-16 08:45


👉目录


1 历史包袱

2 解耦重构

3 NT 架构升级

4 总结




本文是 QQ 25 周年技术巡礼系列的最终章,在前两篇文章中,我们以《QQ 25年技术巡礼丨技术探索下的清新设计,打造轻盈简约的 QQ9 》《QQ 9“傻快傻快”的?!带你看看背后的技术秘密》为题,介绍了QQ 团队在视觉打磨、性能优化背后的探索,本文则将重点介绍手机 QQ 技术架构升级背后的技术故事。

手机 QQ 经过20多年发展,功能不断增加,代码不断累积,架构已经变得越来越臃肿,影响到协作团队开发效率,对用户体验、质量稳定都有较大风险,因此手机 QQ 亟需技术架构的升级。但是对如此庞大的项目进行架构升级,在行业内也是少有的,手机 QQ 架构升级面临的困难和挑战都十分巨大,本文将围绕项目背景、项目历程、项目挑战、项目成果等方面进行深入介绍。





01



历史包袱


在过去20多年里,手机 QQ 从原来纯粹的即时通讯工具,成长为承载了空间、频道、短视频、超秀、增值服务等众多业务的平台。随着业务越来越复杂,最初设计的技术架构变得越来越不适配,业务相互之间耦合越来越严重,时常会遇到改一个问题,牵扯出 N 个问题,问题改不动,代码债越积越多的情况,历史的包袱如同一座大山横在每一位手机 QQ 项目成员面前。


2020年,我们开始着手做架构升级。鉴于手机 QQ 的业务复杂度、代码量级都非常大,评估下来架构升级的工作量大得惊人,于是我们采用分阶段、逐步演进的策略去进行架构升级。整体回顾,手机 QQ 的架构升级时间线是这样的:





02



解耦重构


   2.1 解耦重构架构设计


虽然历史包袱如同一座大山,但是手机 QQ 项目成员也有移山的意志和决心。在2020年,手机 QQ 启动了名为“工业化实践”的技术架构升级项目,这标志着手机 QQ 工程首次系统性地进行业务边界划分、解耦和重构升级。


手 Q 旧架构


从上图可看出,旧架构虽然有模块化和插件化,但存在以下不足:

  1. 主工程承载基础和大部分业务代码,导致基础和业务代码边界不清晰。

  2. 基础核心类持续膨胀、业务之间代码依赖不合理。

  3. 开发效率低:代码修改扩散造成 CR、解冲突、定位问题成本高,同时拖慢编译速度。


针对以上不足,对手机 QQ 工程重新设计了架构。新架构按业务划分模块,业务模块之间是相互解耦的,业务模块之间通过接口和路由进行通信。同时按层级设计划分,层级自上而下依赖,上层模块可依赖下层模块,但下层模块不能逆向依赖上层模块。


手 Q 新架构


新架构的主要收益:

  1. 模块更加内聚,新特性开发影响范围逐步收敛到模块内部,提升研发效率。

  2. 接口更加清晰,依赖数减少,可测性提升,更易于通过单元测试、接口测试保障代码逻辑正确性,提升产品质量。


   2.2 解耦重构的演进历程



手机 QQ 工程各个业务之间的依赖非常严重,对它进行解耦重构不是一蹴而就的事情,需要按阶段制定目标,一步一步地优化。通过整理,手机 QQ 工程解耦重构划分为三个阶段:


  • 阶段一(2020.11 - 2021.2)



基本完成约300万行核心代码的解耦,一共约30个基础模块和40个基础组件完成解耦,核心业务模块基本完成解耦。开发新功能时,因为接口与服务实现是隔离的,通过接口依赖的代码不会再耦合严重。


  • 阶段二(2021.3 - 2021.6)


目标:业务模块继续解耦,建设防劣化机制。

成果:

  1. API 代码占比与依赖数不增加。

  2. 完成防劣化机制搭建,在合入阶段拦住不合理修改。

  3. 完善动态化能力,优化插件与宿主间通信机制和发布效率。


  • 阶段三(2021.7 以后)


目标:进一步完善基础模块和组件化,实现子工程化。

成果:

  1. 完善基础模块和公共组件重构,建立基础模块发布组件流程。

  2. 对频道、小世界业务实现子工程化,独立编译运行。


   2.3 解耦重构收益


在重构基础上,梳理依赖关系,通过三个阶段改善模块化水平,提高编译速度和研发效率,流水线的编译耗时提升50%。代码冲突方面也得到明显改善,对比重构前后数据,冲突文件数减少60%,冲突次数减少30%,大大提升开发效率。





03



NT 架构升级


在成功迈出改革的第一步之后,我们将注意力转向了手机 QQ 面临的版本碎片化问题。不同端各自发展,形成了所谓的“烟囱式”结构,其中代码的复用率极低。这种结构带来了多端体验不一致、端内业务体验参差不齐以及每次版本更新时高昂的开发和维护成本等问题。为了解决这些问题,并在提升用户体验、优化性能和提高研发效率方面实现突破,我们不得不深入思考。正是这些迫切的需求和挑战促使我们启动了改革的第二步——推进手机 QQ NT 架构升级项目。



在 NT 架构设计之初,我们坚定认为不应该继续缝缝补补,而是应该采用最新且合理的技术理念,摒弃了简单的修补式方法。这次升级不仅是技术上的一次大刀阔斧的改造,更是一场深思熟虑的技术转型。我们重视在不造成架构大规模动荡的前提下,制定了一条清晰、可行的实施路径。目标是以更少的人力投入实现更高的工作效率和成果,确保了升级过程中的高效和稳健。这种方法不仅保证了项目的顺利进行,也为未来的技术发展和迭代奠定了坚实的基础。


   3.1 NT 架构落地之难


由于手机 QQ 的历史悠久且拥有庞大的用户群,该项目在业务和用户层面都展现了巨大的复杂性。具体来看,项目层面的挑战包括:

  1. 代码量庞大:手机端代码近千万行,形成了一个技术上的庞然大物。

  2. 测试复杂性高:测试用例众多,功能繁杂,且存在部分文档缺失的情况。

  3. 依赖组件过时:项目中依赖了一些陈旧且缺乏维护的组件,以及大量无人维护的二进制库。

  4. 研发流程保障:在进行架构升级的同时,必须确保研发工作流程能够平稳过渡,以免影响到研发效率。


用户层面上的挑战则包括:

  1. 在长达一年以上的升级过程中,日常版本需要正常迭代。

  2. 用户本地数据量巨大,如超过 10G 的本地消息数据库。

  3. 项目需在技术优化的同时提升用户体验与活跃度,确保技术优化在用户端实现价值。


面对这些复杂度,项目的核心难点主要集中在以下三个方面:

  1. 海量功能项目的架构升级和统一:针对全终端、全功能和全项目团队的整体升级,确保架构升级过程中不能有任何缺失。手机 QQ 是在发展了20多年进行彻底重构,难度空前,没有资料可参考。

  2. IM 全链路架构重写升级:解决陈年技术债,优化消息架构,平稳迁移用户历史数据,并提升消息性能。QQ 消息架构有陈年技术债,很多 QQ 历史版本里,没有统一的消息 ID 生成规则,没有统一的存储和索引方案,消息类型也是无序扩张。所以,既需要对IM全链路重写优化,同时在过程中,还需要平稳迁移用户历史数据,最终完成升级,保护用户数据、用户体验不受影响。

  3. 用户体验提升与活跃数据提升:逐步优化核心功能体验,不影响用户习惯,通过提升体验推动产品数据增长。代码的重写不能全盘一次性推倒重来。核心功能体验要保持,逐步优化,不能影响用户使用习惯。


这些挑战不仅说明了手机 QQ NT 架构升级项目的复杂性,也证明了我们在面对前所未有的技术难题时的决心。


   3.2 NT 架构设计


为了实现架构升级和统一,项目团队先用 C++ 开发了具备 QQ IM 核心功能的跨平台内核层:把 IM 核心业务逻辑(好友、群、频道等消息逻辑、资料与关系链逻辑、图片语音视频等富媒体收发逻辑、实时音视频逻辑等),QQ 通用组件(数据库、协议编解码、网络传输等),以及线程/网络/IO 等通用资源管理模块和操作系统封装部分,由原来的各平台原生语言实现,统一下沉到 C++ 跨平台层。



为了控制项目质量风险,NT 跨平台内核先接入用户量相对较少,对功能补齐紧迫度高的桌面端,完全用新架构重写桌面端。


在桌面端成功完成功能验证和质量测试之后,我们开始了向移动端的迁移工作,并顺利完成了 iOS 和安卓平台的集成。



当然,移动端的接入远远不像图中描述的这般容易,接下来将介绍其中的解决方案和主要过程。


   3.3 IM 全链路重写升级


在新的 NT 架构基础上,对 QQ 来说,最核心的技术升级,是 IM 全链路的升级。IM 消息数据源复杂,历史包袱很重,升级过程的遇到的第一个难点就是数据转换及存量数据迁移到新版本问题:

  • 老版本的 QQ,好友消息没有唯一标识字段,导入和去重影响大。

  • 2012年以前的版本,群消息没有支持漫游,消息无唯一字段。

  • 各平台消息数据格式不同,复杂度高,iOS 和 Android 分别有约200种消息类型。

  • 富媒体(图片、视频、语音、文件)资源,存储的目录结构、命名都不同。

  • 特殊消息,如结构化消息、Ark 消息、小灰条消息,需要做转换,完成业务的梳理和下架工作。

  • 还有因为各种功能的变迁带来的遗留数据问题,如已经退出或者解散的群和讨论组等。


所以,首先需要做 IM 的精简。项目团队基于用户价值考虑,零基思维,完成消息格式统一,对消息和会话类型进行彻底精简,为 QQ 消息长治久安打下基础。



有了全端格式统一和类型精简的基础,开始用大小、性能、安全性综合最优方案设计跨平台统一的全新客户端 DB,然后再考虑旧 DB 的数据,如何平稳升级到新 DB。移动端和桌面端不同,活跃用户全年在线,有些手机本地纯文本消息的 DB 文件超过10G,加上富媒体、文件等,总数据量超过100G,而且移动端又有存储空间小、功耗敏感、后台杀进程等多方面限制,需要设计出一套周密的升级策略,保护用户核心数据资产不丢失。


方案核心要点:

  • 断点续导:移动端场景,进程随时可能被杀或退出。确保消息不丢失、不重复。

  • 用户分级:跟进消息数据大小,用户分为三类,做不同的体验优化,减少对用户的影响。

  • 优化发烫和耗电:限制导入速度,防止手机发烫。手机切后台后停止导入。对消息数据多的用户,引导用户设置在后台导入。

  • 监控:做好各种导入异常上报监控,随时跟进用户反馈。


通过设计周密的升级策略,内部多轮推演,外部从百级开始放量,全方位监控,并用兜底策略保障不丢消息。最终结合监控数据和用户反馈数据,完成了全量用户的全量数据平稳迁移新 DB。


   3.4 核心功能优化提升


不仅是消息,在 NT 架构重写升级过程中,对 QQ 核心功能也一起做了更彻底的重构,手机 QQ 原生功能进行了大规模解耦,通用的部分进行优化并下沉为统一的 NT-Runtime 原生组件(NT 组件服务及框架层)。基于重构后的架构,也对性能进行全面优化。


首先是消息相关核心模块的优化。消息逻辑下沉到 C++ 跨平台,也推动上层进行架构刷新。以聊天窗口(AIO)为例,基于全新数据流架构 + 数据预加载 + UI 逻辑并行化的设计思路,完成单向数据流驱动与异步加载渲染,系统资源全力供给 AIO 消息列表,最终性能指标提升明显,AIO 内查看、跳转、滑动消息,顺畅丝滑。核心技术优化方案:

  • 采用基于单向数据流的 MVI 架构,实现业务解耦。

  • 预加载和异步渲染,实现消息无缝滑动。

  • 消息加载并行化,减少首屏和滑动时的加载时间。

  • 消息动态加载、释放,优化内存占用。

  • 200+业务组件懒加载,实现数据分层和按需加载。


其它 QQ 主场景,如消息列表页、消息与富媒体收发、图片视频查看等,也采用相同的路径进行优化,最终性能全面提升。



04



总结


在手机 QQ 超过20年的发展历程中,应用功能的不断扩展和代码量的持续增长积累了巨大的技术债务,给原有架构带来了沉重的负担。通过一系列的架构演变和技术升级,手机 QQ 成功地实现了从臃肿不堪到模块化、高效、稳定的转变。


客户端架构由各端烟囱式架构逐步升级为多端跨平台复用的 NT 架构,降低多端维护人力成本,提升 QQ 全端开发效率,为 QQ 的持续发展和技术迭代打下了坚实的基础。


展望未来,QQ 将基于 NT 架构,在技术创新的道路上继续前行,不断进行架构优化和技术升级,为用户提供更加流畅稳定的产品体验。


-End-
原创作者 | 何金源



说说QQ伴随着你成长,有没有令你印象深刻的趣事?欢迎评论留言。我们将选取1则优质的评论,送出腾讯云开发者定制眼罩1个(见下图)。5月22日中午12点开奖。


📢📢欢迎加入腾讯云开发者社群,享前沿资讯、大咖干货,找兴趣搭子,交同城好友,更有鹅厂招聘机会、限量周边好礼等你来~


(长按图片立即扫码)





浏览 647
9点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
9点赞
评论
收藏
分享

手机扫一扫分享

分享
举报