不畏移山,手機 QQ 技術架構升級變遷史
手機 QQ 經過 20 多年發展,功能不斷增加,代碼不斷累積,架構已經變得越來越臃腫,影響到協作團隊開發效率,對用戶體驗、質量穩定都有較大風險,因此手機 QQ 亟需技術架構的升級。但是對如此龐大的項目進行架構升級,在行業內也是少有的,手機 QQ 架構升級面臨的困難和挑戰都十分巨大,本文將圍繞項目背景、項目歷程、項目挑戰、項目成果等方面進行深入介紹。
01
歷史包袱
在過去 20 多年裏,手機 QQ 從原來純粹的即時通訊工具,成長爲承載了空間、頻道、短視頻、超秀、增值服務等衆多業務的平臺。隨着業務越來越複雜,最初設計的技術架構變得越來越不適配,業務相互之間耦合越來越嚴重,時常會遇到改一個問題,牽扯出 N 個問題,問題改不動,代碼債越積越多的情況,歷史的包袱如同一座大山橫在每一位手機 QQ 項目成員面前。
2020 年,我們開始着手做架構升級。鑑於手機 QQ 的業務複雜度、代碼量級都非常大,評估下來架構升級的工作量大得驚人,於是我們採用分階段、逐步演進的策略去進行架構升級。整體回顧,手機 QQ 的架構升級時間線是這樣的:
02
解耦重構
2.1 解耦重構架構設計
雖然歷史包袱如同一座大山,但是手機 QQ 項目成員也有移山的意志和決心。在 2020 年,手機 QQ 啓動了名爲 “工業化實踐” 的技術架構升級項目,這標誌着手機 QQ 工程首次系統性地進行業務邊界劃分、解耦和重構升級。
手 Q 舊架構
從上圖可看出,舊架構雖然有模塊化和插件化,但存在以下不足:
-
主工程承載基礎和大部分業務代碼,導致基礎和業務代碼邊界不清晰。
-
基礎核心類持續膨脹、業務之間代碼依賴不合理。
-
開發效率低:代碼修改擴散造成 CR、解衝突、定位問題成本高,同時拖慢編譯速度。
針對以上不足,對手機 QQ 工程重新設計了架構。新架構按業務劃分模塊,業務模塊之間是相互解耦的,業務模塊之間通過接口和路由進行通信。同時按層級設計劃分,層級自上而下依賴,上層模塊可依賴下層模塊,但下層模塊不能逆向依賴上層模塊。
手 Q 新架構
新架構的主要收益:
-
模塊更加內聚,新特性開發影響範圍逐步收斂到模塊內部,提升研發效率。
-
接口更加清晰,依賴數減少,可測性提升,更易於通過單元測試、接口測試保障代碼邏輯正確性,提升產品質量。
2.2 解耦重構的演進歷程
手機 QQ 工程各個業務之間的依賴非常嚴重,對它進行解耦重構不是一蹴而就的事情,需要按階段制定目標,一步一步地優化。通過整理,手機 QQ 工程解耦重構劃分爲三個階段:
- 階段一(2020.11 - 2021.2)
基本完成約 300 萬行核心代碼的解耦,一共約 30 個基礎模塊和 40 個基礎組件完成解耦,核心業務模塊基本完成解耦。開發新功能時,因爲接口與服務實現是隔離的,通過接口依賴的代碼不會再耦合嚴重。
- 階段二(2021.3 - 2021.6)
目標:業務模塊繼續解耦,建設防劣化機制。
成果:
-
API 代碼佔比與依賴數不增加。
-
完成防劣化機制搭建,在合入階段攔住不合理修改。
-
完善動態化能力,優化插件與宿主間通信機制和發佈效率。
- 階段三(2021.7 以後)
目標:進一步完善基礎模塊和組件化,實現子工程化。
成果:
-
完善基礎模塊和公共組件重構,建立基礎模塊發佈組件流程。
-
對頻道、小世界業務實現子工程化,獨立編譯運行。
2.3 解耦重構收益
在重構基礎上,梳理依賴關係,通過三個階段改善模塊化水平,提高編譯速度和研發效率,流水線的編譯耗時提升 50%。代碼衝突方面也得到明顯改善,對比重構前後數據,衝突文件數減少 60%,衝突次數減少 30%,大大提升開發效率。
03
NT 架構升級
在成功邁出改革的第一步之後,我們將注意力轉向了手機 QQ 面臨的版本碎片化問題。不同端各自發展,形成了所謂的 “煙囪式” 結構,其中代碼的複用率極低。這種結構帶來了多端體驗不一致、端內業務體驗參差不齊以及每次版本更新時高昂的開發和維護成本等問題。爲了解決這些問題,並在提升用戶體驗、優化性能和提高研發效率方面實現突破,我們不得不深入思考。正是這些迫切的需求和挑戰促使我們啓動了改革的第二步——推進手機 QQ NT 架構升級項目。
在 NT 架構設計之初,我們堅定認爲不應該繼續縫縫補補,而是應該採用最新且合理的技術理念,摒棄了簡單的修補式方法。這次升級不僅是技術上的一次大刀闊斧的改造,更是一場深思熟慮的技術轉型。我們重視在不造成架構大規模動盪的前提下,制定了一條清晰、可行的實施路徑。目標是以更少的人力投入實現更高的工作效率和成果,確保了升級過程中的高效和穩健。這種方法不僅保證了項目的順利進行,也爲未來的技術發展和迭代奠定了堅實的基礎。
3.1 NT 架構落地之難
由於手機 QQ 的歷史悠久且擁有龐大的用戶羣,該項目在業務和用戶層面都展現了巨大的複雜性。具體來看,項目層面的挑戰包括:
-
代碼量龐大:手機端代碼近千萬行,形成了一個技術上的龐然大物。
-
測試複雜性高:測試用例衆多,功能繁雜,且存在部分文檔缺失的情況。
-
依賴組件過時:項目中依賴了一些陳舊且缺乏維護的組件,以及大量無人維護的二進制庫。
-
研發流程保障:在進行架構升級的同時,必須確保研發工作流程能夠平穩過渡,以免影響到研發效率。
用戶層面上的挑戰則包括:
-
在長達一年以上的升級過程中,日常版本需要正常迭代。
-
用戶本地數據量巨大,如超過 10G 的本地消息數據庫。
-
項目需在技術優化的同時提升用戶體驗與活躍度,確保技術優化在用戶端實現價值。
面對這些複雜度,項目的核心難點主要集中在以下三個方面:
-
海量功能項目的架構升級和統一:針對全終端、全功能和全項目團隊的整體升級,確保架構升級過程中不能有任何缺失。手機 QQ 是在發展了 20 多年進行徹底重構,難度空前,沒有資料可參考。
-
IM 全鏈路架構重寫升級:解決陳年技術債,優化消息架構,平穩遷移用戶歷史數據,並提升消息性能。QQ 消息架構有陳年技術債,很多 QQ 歷史版本裏,沒有統一的消息 ID 生成規則,沒有統一的存儲和索引方案,消息類型也是無序擴張。所以,既需要對 IM 全鏈路重寫優化,同時在過程中,還需要平穩遷移用戶歷史數據,最終完成升級,保護用戶數據、用戶體驗不受影響。
-
用戶體驗提升與活躍數據提升:逐步優化核心功能體驗,不影響用戶習慣,通過提升體驗推動產品數據增長。代碼的重寫不能全盤一次性推倒重來。核心功能體驗要保持,逐步優化,不能影響用戶使用習慣。
這些挑戰不僅說明了手機 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 架構,在技術創新的道路上繼續前行,不斷進行架構優化和技術升級,爲用戶提供更加流暢穩定的產品體驗。
原創作者 | 何金源
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/nNBuEc2SRXvNP_B5_kMF0g