Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文由騰訊技術何金源分享,原題“不畏移山,手機QQ技術架構升級變遷史”,本文進行了排版和內容優化等。

          1、引言

          接上篇《總是被低估,從未被超越,揭秘QQ極致絲滑背后的硬核IM技術優化》,本文則將重點介紹手機 QQ 客戶端技術架構升級背后的故事。

          手機 QQ 經過20多年發展,功能不斷增加,代碼不斷累積,架構已經變得越來越臃腫,影響到協作團隊開發效率,對用戶體驗、質量穩定都有較大風險,因此手機 QQ 亟需技術架構的升級。但是對如此龐大的項目進行架構升級,在行業內也是少有的,手機 QQ 架構升級面臨的困難和挑戰都十分巨大,本文將圍繞最新手機 QQ 客戶端項目背景、項目歷程、項目挑戰、項目成果等方面進行深入介紹。

           
           

          2、手機QQ的歷史包袱

          在過去20多年里,手機 QQ 從原來純粹的即時通訊IM工具,成長為承載了空間、頻道、短視頻、超秀、增值服務等眾多業務的平臺。

          隨著業務越來越復雜,最初設計的技術架構變得越來越不適配,業務相互之間耦合越來越嚴重,時常會遇到改一個問題,牽扯出 N 個問題,問題改不動,代碼債越積越多的情況,歷史的包袱如同一座大山橫在每一位手機 QQ 項目成員面前。

          2020年,我們開始著手做架構升級。

          鑒于手機 QQ 的業務復雜度、代碼量級都非常大,評估下來架構升級的工作量大得驚人,于是我們采用分階段、逐步演進的策略去進行架構升級。

          整體回顧,手機 QQ 的架構升級時間線是這樣的:

          3、“解耦重構”架構設計

          雖然歷史包袱如同一座大山,但是手機 QQ 項目成員也有移山的意志和決心。

          在2020年,手機 QQ 啟動了名為“工業化實踐”的技術架構升級項目,這標志著手機 QQ 工程首次系統性地進行業務邊界劃分、解耦和重構升級。

          從上圖可看出,舊架構雖然有模塊化和插件化,但存在以下不足:

          • 1)邊界不清晰:主工程承載基礎和大部分業務代碼,導致基礎和業務代碼邊界不清晰;
          • 2)代碼耦合緊:基礎核心類持續膨脹、業務之間代碼依賴不合理;
          • 3)開發效率低:代碼修改擴散造成 CR、解沖突、定位問題成本高,同時拖慢編譯速度。

          針對以上不足,對手機 QQ 工程重新設計了架構:

          1)新架構按業務劃分模塊,業務模塊之間是相互解耦的,業務模塊之間通過接口和路由進行通信;

          2)同時按層級設計劃分,層級自上而下依賴,上層模塊可依賴下層模塊,但下層模塊不能逆向依賴上層模塊。

          手 Q 客戶端新架構:

          新架構的主要收益:

          • 1)模塊更加內聚:新特性開發影響范圍逐步收斂到模塊內部,提升研發效率;
          • 2)接口更加清晰:依賴數減少,可測性提升,更易于通過單元測試、接口測試保障代碼邏輯正確性,提升產品質量。

          4、“解耦重構”的實踐歷程

          4.1概述

          手機 QQ 工程各個業務之間的依賴非常嚴重,對它進行解耦重構不是一蹴而就的事情,需要按階段制定目標,一步一步地優化。

          通過整理,手機 QQ 工程解耦重構劃分為以下三個階段。

          4.2階段一(2020.11 - 2021.2)

          基本完成約300萬行核心代碼的解耦,一共約30個基礎模塊和40個基礎組件完成解耦,核心業務模塊基本完成解耦。

          開發新功能時,因為接口與服務實現是隔離的,通過接口依賴的代碼不會再耦合嚴重。

          4.3階段二(2021.3 - 2021.6)

          目標:業務模塊繼續解耦,建設防劣化機制。

          成果:

          • 1)API 代碼占比與依賴數不增加;
          • 2)完成防劣化機制搭建,在合入階段攔住不合理修改;
          • 3)完善動態化能力,優化插件與宿主間通信機制和發布效率。

          4.4階段三(2021.7 以后)

          目標:進一步完善基礎模塊和組件化,實現子工程化。

          成果:

          • 1)完善基礎模塊和公共組件重構,建立基礎模塊發布組件流程;
          • 2)對頻道、小世界業務實現子工程化,獨立編譯運行。

          5、“解耦重構”的技術收益

          在重構基礎上,梳理依賴關系,通過三個階段改善模塊化水平,提高編譯速度和研發效率,流水線的編譯耗時提升50%。

          代碼沖突方面也得到明顯改善,對比重構前后數據,沖突文件數減少60%,沖突次數減少30%,大大提升開發效率。

          6、手機QQ下一代架構:NT架構

          在成功邁出改革的第一步之后,我們將注意力轉向了手機 QQ 面臨的版本碎片化問題。

          不同端各自發展,形成了所謂的“煙囪式”結構,其中代碼的復用率極低。這種結構帶來了多端體驗不一致、端內業務體驗參差不齊以及每次版本更新時高昂的開發和維護成本等問題。

          為了解決這些問題,并在提升用戶體驗、優化性能和提高研發效率方面實現突破,我們不得不深入思考。

          正是這些迫切的需求和挑戰促使我們啟動了改革的第二步——推進手機 QQ NT 架構升級項目。

          在 NT 架構設計之初,我們堅定認為不應該繼續縫縫補補,而是應該采用最新且合理的技術理念,摒棄了簡單的修補式方法。這次升級不僅是技術上的一次大刀闊斧的改造,更是一場深思熟慮的技術轉型。

          我們重視在不造成架構大規模動蕩的前提下,制定了一條清晰、可行的實施路徑。目標是以更少的人力投入實現更高的工作效率和成果,確保了升級過程中的高效和穩健。這種方法不僅保證了項目的順利進行,也為未來的技術發展和迭代奠定了堅實的基礎。

          7、NT架構落地之難

          由于手機 QQ 的歷史悠久且擁有龐大的用戶群,該項目在業務和用戶層面都展現了巨大的復雜性。

          具體來看,項目層面的挑戰包括:

          • 1)代碼總量龐大:手機端代碼近千萬行,形成了一個技術上的龐然大物;
          • 2)測試復雜性高:測試用例眾多,功能繁雜,且存在部分文檔缺失的情況;
          • 3)依賴組件過時:項目中依賴了一些陳舊且缺乏維護的組件,以及大量無人維護的二進制庫;
          • 4)研發流程保障:在進行架構升級的同時,必須確保研發工作流程能夠平穩過渡,以免影響到研發效率。

          用戶層面上的挑戰則包括:

          • 1)在長達一年以上的升級過程中,日常版本需要正常迭代;
          • 2)用戶本地數據量巨大,如超過 10G 的本地消息數據庫;
          • 3)項目需在技術優化的同時提升用戶體驗與活躍度,確保技術優化在用戶端實現價值。

          面對這些復雜度,項目的核心難點主要集中在以下三個方面。

          1)海量功能項目的架構升級和統一:針對全終端、全功能和全項目團隊的整體升級,確保架構升級過程中不能有任何缺失。手機 QQ 是在發展了20多年進行徹底重構,難度空前,沒有資料可參考。

          2)IM 全鏈路架構重寫升級:解決陳年技術債,優化消息架構,平穩遷移用戶歷史數據,并提升消息性能。QQ 消息架構有陳年技術債,很多 QQ 歷史版本里,沒有統一的消息 ID 生成規則,沒有統一的存儲和索引方案,消息類型也是無序擴張。所以,既需要對IM全鏈路重寫優化,同時在過程中,還需要平穩遷移用戶歷史數據,最終完成升級,保護用戶數據、用戶體驗不受影響。

          3)用戶體驗提升與活躍數據提升:逐步優化核心功能體驗,不影響用戶習慣,通過提升體驗推動產品數據增長。代碼的重寫不能全盤一次性推倒重來。核心功能體驗要保持,逐步優化,不能影響用戶使用習慣。

          這些挑戰不僅說明了手機 QQ NT 架構升級項目的復雜性,也證明了我們在面對前所未有的技術難題時的決心。

          8、NT架構設計

          為了實現架構升級和統一,項目團隊先用 C++ 開發了具備 QQ IM 核心功能的跨平臺內核層:把 IM 核心業務邏輯(好友、群、頻道等消息邏輯、資料與關系鏈邏輯、圖片語音視頻等富媒體收發邏輯、實時音視頻邏輯等),QQ 通用組件(數據庫、協議編解碼、網絡傳輸等),以及線程/網絡/IO 等通用資源管理模塊和操作系統封裝部分,由原來的各平臺原生語言實現,統一下沉到 C++ 跨平臺層。

          為了控制項目質量風險,NT 跨平臺內核先接入用戶量相對較少,對功能補齊緊迫度高的桌面端,完全用新架構重寫桌面端。

          在桌面端成功完成功能驗證和質量測試之后,我們開始了向移動端的遷移工作,并順利完成了 iOS 和安卓平臺的集成。

          當然,移動端的接入遠遠不像圖中描述的這般容易,接下來將介紹其中的解決方案和主要過程。

          9、 IM客戶端全鏈路重寫升級

          在新的 NT 架構基礎上,對 QQ 來說,最核心的技術升級,是 IM 全鏈路的升級。

          IM 消息數據源復雜,歷史包袱很重,升級過程的遇到的第一個難點就是數據轉換及存量數據遷移到新版本問題。

          比如:

          • 1)老版本的 QQ,好友消息沒有唯一標識字段,導入和去重影響大;
          • 2)2012年以前的版本,群消息沒有支持漫游,消息無唯一字段;
          • 3)各平臺消息數據格式不同,復雜度高,iOS 和 Android 分別有約200種消息類型;
          • 4)富媒體(圖片、視頻、語音、文件)資源,存儲的目錄結構、命名都不同;
          • 5)特殊消息,如結構化消息、Ark 消息、小灰條消息,需要做轉換,完成業務的梳理和下架工作;
          • 6)還有因為各種功能的變遷帶來的遺留數據問題,如已經退出或者解散的群和討論組等。

          所以,首先需要做 IM 的精簡。項目團隊基于用戶價值考慮,零基思維,完成消息格式統一,對消息和會話類型進行徹底精簡,為 QQ 消息長治久安打下基礎。

          有了全端格式統一和類型精簡的基礎,開始用大小、性能、安全性綜合最優方案設計跨平臺統一的全新客戶端 DB,然后再考慮舊 DB 的數據,如何平穩升級到新 DB。

          移動端和桌面端不同,活躍用戶全年在線,有些手機本地純文本消息的 DB 文件超過10G,加上富媒體、文件等,總數據量超過100G,而且移動端又有存儲空間小、功耗敏感、后臺殺進程等多方面限制,需要設計出一套周密的升級策略,保護用戶核心數據資產不丟失。

          方案核心要點:

          • 1)斷點續導:移動端場景,進程隨時可能被殺或退出。確保消息不丟失、不重復;
          • 2)用戶分級:跟進消息數據大小,用戶分為三類,做不同的體驗優化,減少對用戶的影響;
          • 3)優化發燙和耗電:限制導入速度,防止手機發燙。手機切后臺后停止導入。對消息數據多的用戶,引導用戶設置在后臺導入;
          • 4)監控:做好各種導入異常上報監控,隨時跟進用戶反饋。

          通過設計周密的升級策略,內部多輪推演,外部從百級開始放量,全方位監控,并用兜底策略保障不丟消息。最終結合監控數據和用戶反饋數據,完成了全量用戶的全量數據平穩遷移新 DB。

          10、客戶端核心功能優化提升

          不僅是消息,在 NT 架構重寫升級過程中,對 QQ 核心功能也一起做了更徹底的重構,手機 QQ 原生功能進行了大規模解耦,通用的部分進行優化并下沉為統一的 NT-Runtime 原生組件(NT 組件服務及框架層)。基于重構后的架構,也對性能進行全面優化。

          首先是消息相關核心模塊的優化。

          消息邏輯下沉到 C++ 跨平臺,也推動上層進行架構刷新。

          以聊天窗口(AIO)為例:基于全新數據流架構 + 數據預加載 + UI 邏輯并行化的設計思路,完成單向數據流驅動與異步加載渲染,系統資源全力供給 AIO 消息列表,最終性能指標提升明顯,AIO 內查看、跳轉、滑動消息,順暢絲滑。

          核心技術優化方案:

          • 1)采用基于單向數據流的 MVI 架構,實現業務解耦;
          • 2)預加載和異步渲染,實現消息無縫滑動;
          • 3)消息加載并行化,減少首屏和滑動時的加載時間;
          • 4)消息動態加載、釋放,優化內存占用。
          • 5)200+業務組件懶加載,實現數據分層和按需加載。

          其它 QQ 主場景,如消息列表頁、消息與富媒體收發、圖片視頻查看等,也采用相同的路徑進行優化,最終性能全面提升。

          11、本文小結

          在手機 QQ 超過20年的發展歷程中,應用功能的不斷擴展和代碼量的持續增長積累了巨大的技術債務,給原有的客戶端架構帶來了沉重的負擔。最新版手機QQ通過一系列的架構演變和技術升級,成功地實現了從臃腫不堪到模塊化、高效、穩定的轉變。

          客戶端架構由各端煙囪式架構逐步升級為多端跨平臺復用的 NT 架構,降低多端維護人力成本,提升 QQ 全端開發效率,為 QQ 的持續發展和技術迭代打下了堅實的基礎。

          展望未來,QQ 將基于 NT 架構,在技術創新的道路上繼續前行,不斷進行架構優化和技術升級,為用戶提供更加流暢穩定的產品體驗。

          12、相關資料

          [1] 總是被低估,從未被超越,揭秘QQ極致絲滑背后的硬核IM技術優化

          [2] 大型IM工程重構實踐:企業微信Android端的重構之路

          [3] 企業微信針對百萬級組織架構的客戶端性能優化實踐

          [4] 微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題

          [5] 騰訊技術分享:Android版手機QQ的緩存監控與優化實踐

          [6] 騰訊技術分享:Android手Q的線程死鎖監控系統技術實踐

          [7] 全面解密新QQ桌面版的Electron內存優化實踐

          [8] 移動端IM實踐:iOS版微信界面卡頓監測方案

          [9] 微信團隊原創分享:Android版微信的臃腫之困與模塊化實踐之路

          [10] 微信Windows端IM消息數據庫的優化實踐:查詢慢、體積大、文件損壞等

          [11] 微信團隊分享:微信支付代碼重構帶來的移動端軟件架構上的思考

          [12] 微信客戶端團隊負責人技術訪談:如何著手客戶端性能監控和優化

          [13] 抖音技術分享:飛鴿IM桌面端基于Rust語言進行重構的技術選型和實踐總結

          [14] 阿里技術分享:閑魚IM基于Flutter的移動端跨端改造實踐

          [15] QQ設計團隊分享:新版 QQ 8.0 語音消息改版背后的功能設計思路

          13、更多鵝廠技術文章匯總

          1. 微信朋友圈千億訪問量背后的技術挑戰和實踐總結
          2. 騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(圖片壓縮篇)
          3. IM全文檢索技術專題(二):微信移動端的全文檢索多音字問題解決方案
          4. 微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐
          5. 微信團隊分享:iOS版微信是如何防止特殊字符導致的炸群、APP崩潰的?
          6. 微信團隊分享:微信Android版小視頻編碼填過的那些坑
          7. IM全文檢索技術專題(一):微信移動端的全文檢索優化之路
          8. 企業微信客戶端中組織架構數據的同步更新方案優化實戰
          9. 微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解
          10. 微信“紅包照片”背后的技術難題
          11. 移動端IM實踐:iOS版微信的多設備字體適配方案探討
          12. 騰訊信鴿技術分享:百億級實時消息推送的實戰經驗
          13. IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)
          14. 騰訊技術分享:GIF動圖技術詳解及手機QQ動態表情壓縮技術實踐
          15. 微信團隊分享:Kotlin漸被認可,Android版微信的技術嘗鮮之旅
          16. 社交軟件紅包技術解密(一):全面解密QQ紅包技術方案——架構、技術實現等
          17. 社交軟件紅包技術解密(四):微信紅包系統是如何應對高并發的
          18. 社交軟件紅包技術解密(十):手Q客戶端針對2020年春節紅包的技術實踐
          19. 微信團隊分享:極致優化,iOS版微信編譯速度3倍提升的實踐總結
          20. IM“掃一掃”功能很好做?看看微信“掃一掃識物”的完整技術實現
          21. 微信團隊分享:微信支付代碼重構帶來的移動端軟件架構上的思考
          22. IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總
          23. 微信團隊分享:微信直播聊天室單房間1500萬在線的消息架構演進之路
          24. 企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等
          25. IM全文檢索技術專題(四):微信iOS端的最新全文檢索技術優化實踐
          26. 微信團隊分享:微信后臺在海量并發請求下是如何做到不崩潰的
          27. 微信Windows端IM消息數據庫的優化實踐:查詢慢、體積大、文件損壞等
          28. 微信技術分享:揭秘微信后臺安全特征數據倉庫的架構設計
          29. IM跨平臺技術學習(九):全面解密新QQ桌面版的Electron內存優化實踐
          30. 企業微信針對百萬級組織架構的客戶端性能優化實踐
          31. 揭秘企業微信是如何支持超大規模IM組織架構的——技術解讀四維關系鏈
          32. 微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題
          33. 微信團隊分享:微信后端海量數據查詢從1000ms降到100ms的技術實踐
          34. 大型IM工程重構實踐:企業微信Android端的重構之路
          35. IM技術干貨:假如你來設計微信的群聊,你該怎么設計?
          36. 微信團隊分享:來看看微信十年前的IM消息收發架構,你做到了嗎
          37. 長連接網關技術專題(十一):揭秘騰訊公網TGW網關系統的技術架構演進


          (本文已同步發布于:http://www.52im.net/thread-4658-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 汉阴县| 会东县| 维西| 缙云县| 壤塘县| 嵊州市| 西宁市| 苏州市| 永兴县| 桂林市| 新化县| 兴宁市| 资兴市| 泸定县| 京山县| 隆子县| 湖南省| 山东省| 庄河市| 稷山县| 黔西| 沁阳市| 洪洞县| 两当县| 松桃| 平原县| 环江| 兰溪市| 乐业县| 福建省| 乌什县| 卢湾区| 邻水| 萨迦县| 无极县| 南靖县| 云梦县| 黄石市| 易门县| 巴塘县| 临夏县|