手機QQ的移動化實踐之路
2014年12月19日~20日舉行的ArchSummit北京2014大會上,騰訊即時通訊平臺部技術總監(jiān)范瑞彬做了題為《手機QQ的移動化實踐之路》(幻燈片下載)的演講,介紹了手機QQ在服務海量移動用戶方面經歷了的一些經驗。
范瑞彬(hata fan),騰訊公司即時通訊平臺部技術總監(jiān),T4專家。2004年加入騰訊,長期負責手機QQ后臺整體建設,完整地經歷了手機QQ從數千人在線到億級在線的整個過程,見證了十多年來移動互聯網服務的高速發(fā)展。目前主要負責QQ整體的接入平臺建設,在海量分布式后臺架構、IM系統(tǒng)設計、移動業(yè)務架構設計等方面積累了多年實踐經驗。
本文系根據演講內容整理而成。
演講主要涉及3個部分。
第一,移動環(huán)境的特點。
第二,針對移動環(huán)境的特點,如何做好接入?
第三,架構設計理念方面的變化。
下圖包含了云、管、端三個部分,多種終端通過多種網絡訪問云端的服務。上面紅色部分是接入層,是首先會受到影響的。下面是邏輯存儲、運營支撐和安全體系,這個系統(tǒng)目前終端同時在線過億。終端每秒的請求量差不多千萬,一天的請求量在數千億的量級。
移動環(huán)境的特點
可以從三個方面看移動環(huán)境的特點。首先是移動網絡,大家首先感覺是慢,而且流量又挺貴的。它還有很多種制式,差別也很大。還有終端的特點,相對PC來說手機終端資源(CPU、內存、電量等)是受限的,永遠是不夠用的。而且終端的平臺很多,機型多,能力差異也非常大。還有一個很重要的特點就是移動性,可以隨身攜帶,可以隨時隨地利用碎片化的時間,環(huán)境多變,使用頻繁。
如何做好接入
面對這些環(huán)境的變化,接入首先會受到影響,而接入又是所有服務的基石。所以在移動環(huán)境下面,提供高質量的接入服務非常重要。如果將接入比作開車,那首先要選擇一條快速的路線,這就相當于路由調度策略。另外還需要有一輛好車,車要快,類似于數據傳輸加速。然而選了一條好的路線,也有了一輛快車,并不代表就能快速到達目的地,尤其是非WIFI接入時,新增了基站、大量新增的網源系統(tǒng),非常復雜。這里面有一些規(guī)則需要了解,如果不了解的話可能這些就是坑,而遇到了坑可能會翻車,所以不能把它當成黑盒,所以需要熟悉路況。路況很復雜,車也很復雜,跑的過程當中難免會遇到異常,所以還得會修車,不能拋錨,這幾點是接入的幾個主要工作。
1. 路由調度(選快路)
分布式接入,在南方、北方和中部選擇了三個地區(qū),各自部署了一個點,每個點也覆蓋了三大運營商,這是基礎工作。
這時還有一個問題,如果中小運營商用戶也訪問到在三大運營商部署的服務,會存在跨網訪問,質量很差。所以又建設了一個內容加速機房,它有獨立IP,而且是TCP互聯,路由直達,這樣中小運營商的質量可以得到明顯改善。針對海外用戶,最初在香港部署了一個點,后來又在全球各大洲,每個洲選擇了一個點,海外用戶就近訪問加速點,通過加速點再訪問國內的服務器。
部署是在不斷優(yōu)化的,調度也需要更精準的體現。所謂調度,無非就是說什么時候,哪些用戶該連到哪些server。所以這里可以分用戶、server、時間三個維度。比如說用戶,細化到每個網關;server,把用戶調度到質量較高的server上面去;時間比較好理解,因為移動網絡經常有波動,需要快速地發(fā)現波動,并及時自動干預,把它調度走。
還有一個很常見的問題,就是頻繁切換網絡。用戶可能每天都在不同運營商,不同的網絡之間來回切換。連接的時候不用域名,直接用IP,那如何保證用戶不管怎么樣切換網絡,都能連接到連到他應該連接的server上面呢?假如說用戶第一次連某個網絡時,他會使用本地默認列表,連到server時,如果server發(fā)現不是最優(yōu)的,會及時糾正,下發(fā)一份新的server列表。開發(fā)團隊干脆把用戶最近使用的50個接入點統(tǒng)統(tǒng)緩存下來。
2. 數據傳輸加速(造快車)
做完了調度相當于選擇了一條快速路線,這是不夠的,還要想辦法造一輛快的車。
首先是不用域名,直接用IP。這樣可以減少域名解析的開銷,更重要的是,可以避免域名解析帶來的各種故障,還可以減少一些被屏蔽和封掉的可能。
第二點是重用連接、預連接。比如說QQ里面發(fā)圖的時候,其實用戶還在選擇圖片的時候,會先把連接建立起來,而且用戶傳完圖以后連接不會立即斷掉,會維持一段時間,后面有批量圖的時候可以繼續(xù)使用,減少一次連接的時間可以減少幾百毫秒。
第三點是精簡協(xié)議和邏輯。
第四點是參數調優(yōu)。比如說“擁塞窗口”(congestion window,CWND),server的操作系統(tǒng)默認是4,建議調大一點,可以調到10,這樣可以減輕慢啟動對傳輸帶來的影響。還有最大傳輸單元(Maximum Transmission Unit,MTU),之前跟運營商的朋友交流,他們給的建議是不要大于1400,現在基本上都是按照這個策略來做的。還有重新傳輸超時(Retransmission Timeout, RTO),一般設3秒左右,系統(tǒng)默認值設的是1。
還有一點叫高帶寬時延積環(huán)境,在這種環(huán)境下面會遇到帶寬吃不滿,存在浪費的問題。以前網絡都是2G網絡的功能機時代。當時傳圖片大部分用的都是單連接。最近幾年,網絡越來越多,種類也越來越多,而且網絡也越來越好。所以系統(tǒng)也進行了改進,可以根據網絡狀況動態(tài)地選擇合適的連接數。比如說經過理論分析以及實驗驗證,開發(fā)團隊發(fā)現其實在WIFI、3G、4G比較好的網絡下面?zhèn)鬏敶髷祿r,用雙連接比單連接提升至少10%,而且越好的網絡提升效果越明顯。
3.移動網絡環(huán)境不是黑盒(熟路況)
不能簡單地把移動網絡環(huán)境當成黑核來處理,有些細節(jié)知識是需要了解的。
第一,要了解國內移動網關的一些設置,比如說它會限制某個包傳輸的大小,如果超過的話直接失敗。之前跟設備廠商了解,華為很多網關設置的是10M,但是各家都不一樣,也沒有什么標準。還有網關很多時候對傳輸時間有限制,這個也是各家不一樣的。了解了這些細節(jié),肯定要很好地支持分片和斷點續(xù)傳,否則在某些地區(qū)可能會出問題。
第二,網關對很多標準的理解和實現,各家也是不一樣的,尤其像影響比較大的,比如說對HTTP協(xié)議的理解和實現。比如說在HTTP的標準文檔里面,提了一個range,但是沒有強制去做,有的廠商支持的就不是太好。曾經遇到過一種情況,頭部用到了range,在分片傳輸圖片時,運營商網關把它過濾掉了,客戶端就不知道下一次該從哪里發(fā),所以可能又從第一片開始發(fā),這種情況下,如果客戶端沒有做好相關保護,就非常危險,會大量的重傳,用戶流量會被大量消耗。這就是需要注意的地方,盡量不要在HTTP頭部加一些字段,需要傳一些信息的話,可以放在包體里面,自己解析和理解。
第三,tcp_tw_recycle。用戶說網絡是好的,但是連不上server。抓包分析發(fā)現,客戶端三次握手的包已經發(fā)過來了,但是server沒有回。這是什么問題呢?經過深入分析,研究了一下協(xié)議棧,以及一些參數設置,后來發(fā)現,假如tcp_tw_recycle是開啟的,server會檢查對端同一個網關IP發(fā)過來的包,時間是不是遞增的,如果不是遞增的可能會丟掉。但是移動網絡環(huán)境下,這是很難保證的。關閉tcp_tw_recycle,問題就解決了。后來這成了外網接入層的標準配置。
第四,端口受限。有人反映某些地區(qū)的用戶連server的某些端口連不上,或者是連接質量比較差。比如曾經發(fā)現香港數碼通的用戶連8080端口的質量非常差,很慢;還發(fā)現有些機場WIFI,比如說深圳機場WIFI,除了8080和43之外的斷口都封掉了,用其他的端口用戶也連不上。開發(fā)團隊意識到,不應該被動地靠用戶的反饋來發(fā)現問題和解決問題,所以建設了一套自動的系統(tǒng),根據海量的數據去分析,根據分析結果,server在給客戶端返回合適接入列表時,優(yōu)先選擇質量高的端口,而且也盡量注意端口搭配的多樣性,這樣可以提升接入質量。
最后看一下信令風暴。其實從09年開始,手機QQ這邊每年會被運營商朋友拉過去一起探討這個問題,雙方本著互相理解、合作共贏的態(tài)度來對待這個問題。除了建立一些雙方認可的虛擬消耗運算模型之外,雙方還就移動業(yè)務達成了技術共識。比如說減少定時包,減少不必要的及時包,因為有些包真的不一定要非常及時??梢赃m當做一些緩存和合并。還有一點就是要有流控,萬一客戶端有BUG,大量的發(fā)包,這時候有壓跨移動網絡的可能,并不僅僅是數據網,它對電信網也有影響,所以server這時要有能力控制客戶端發(fā)包的策略和頻率,這樣HTTP服務才能讓人放心一點。
4.異常處理(會修車)
比如說業(yè)務用的是TCP長連接,但是請求有可能被劫持,可能會返回到奇怪的HTML頁面,最常見的是WIFI的認證注冊,這時需要及時準確地發(fā)現這些問題,展現出來提示用戶。
有一種網絡抖動叫先發(fā)后到,需要做一些保護。比如說要求客戶端發(fā)包的時候一定要遞增,而且即使進程被殺掉重新再起來,也要保證這次發(fā)包比上次大。借助這個大小能知道真實發(fā)包時間的先后順序。
終端休眠,終端是為了省電,肯定有一些休眠策略,App為了應對這些策略,有一些自動喚醒機制,做一些自己想做的事。如果用Wakelock,拿到這個鎖之后,系統(tǒng)再也進入不了休眠了,這個鎖一般用兩三秒就足夠了,一定要慎重。
最后是App健康和智能檢測。客戶端不能保證百分之百不出問題,有時候確實有可能在一些小概率的情況下,存在異常的點,它有可能會觸發(fā)一些頻繁大量的發(fā)包策略。大量的發(fā)包會把用戶的流量大量消耗掉,而且這還算輕的,更嚴重的是如果有較多用戶都出現這樣的問題,可能不是流量消耗的問題,而存在把移動網絡壓跨的可能,移動網絡真的很脆弱。
《刑法》中有一條罪叫破壞通信罪,可以判三到七年,所以這種工作很危險,也是有責任的。壓垮移動網絡后果很嚴重,要想辦法極早發(fā)現和干預。怎么辦呢?server可以做一些準實時的流量消耗分析,如果發(fā)現在單位時間內用戶流量超過某個異常值,就及時干預,而不是事后檢查。比如可以把用戶直接踢下線,或者更嚴重一點,直接讓客戶端的App自動自殺。
除了流量的問題,還有一些問題也是很隱蔽的,比如說用戶的流量看起來沒有太大變化。但是可能客戶端有bug或者是設計不當,調用了幾次后臺操作,這個版本發(fā)出去的話,調用可能會增加好幾倍甚至更多,后臺的壓力就非常大,于是又是過載保護,又是緊急擴容,這個也不是開發(fā)團隊希望看到的,需要有更好的辦法來解決它。比如可以分析這個版本,每個用戶的使用頻率。如果發(fā)現這個版本與上個版本相比,使用頻率變化很大,多了很多,而且又沒有提前報備,這里肯定有問題,就把這個問題抓出來,這些事情靠測試同學是不現實的,他很難測試到這些問題,這些問題需要技術同學自己想辦法通過做智能數據分析來發(fā)現。
架構設計的理念
根據大量的實踐,開發(fā)團隊提煉出兩個關鍵詞:輕量交互和差異服務。
1. 輕量交互
輕量交互,其實核心思想就是節(jié)省,主要思想是從協(xié)議層面以及邏輯層面做一些精簡、合并、壓縮、消峰、異步等等。
減少交互步驟。客戶端一次請求,盡量把信息都拿下去,后臺也盡量把相關的信息都加進去,完整地帶下去,減少交互步驟。這里要求后臺要多主動地做一些聚合工作,一些協(xié)議要重新設計。
精簡交互信息,盡量減少每一次傳輸過程中的信息。有個原則,就是不用的信息盡量不要拉,這里要求開發(fā)團隊在協(xié)議設計的時候要非常靈活和細致,要支持增量更新和同步邏輯。
復用包頭。一般做協(xié)議設計的時候有包頭和包體,包頭里面放一些賬號信息、身份憑證,還有版本信息。尤其隨著現在安全壓力越來越大,形勢越來越嚴峻,身份憑證可能會越來越長。其實這些信息沒必要每次都帶,可以在接入server時做一些緩存,后面的包就不需要這些信息了,這樣的話每個包可以減少幾十個字節(jié),甚至更可觀。這樣算起來收益是很大的,不光能幫用戶省流量,因為傳的內容燒,也能加快速度,對體驗也有改善,勿以善小而不為。
智能合并壓縮。這里需要對業(yè)務邏輯有深入的了解。不是所有的包一定要最快響應,可以請求分一下優(yōu)先級,哪些是需要及時響應的,一定要及時保證。哪些是可以降級的,不需要很及時。可以把大量的不需要及時響應的包做一些延遲,這個延遲不僅是為了解決運營商的消耗問題,延遲以后可以做壓縮。當然具體延遲多久,可能要根據具體業(yè)務的場景來看。
客戶端異步削峰。還是細分問題,把一些不重要的包或者是當前這個不是立即需要的可以往后放,先讓用戶快點接入進來。同樣,客戶端也需要注意不要把UI繪制跟存儲放在一個線程里面做,避免卡頓。
2.差異服務
可以把差異服務理解成個性化服務,針對網絡情況和終端優(yōu)化應用。下面具體看看。
怎么做好預拉取。比如說QQ會拉消息,拉過來的一堆消息里面可能有一些是圖片消息,一開始看到這些圖片消息只是縮略圖。那何時去下載這些縮略圖的原圖呢?如果說等用戶點了之后再去下載,自然大家會覺得這個很慢,體驗不好。那提前下載該怎么做呢?這里要細致和全面一點。比如說可能要細分網絡狀況,在非WIFI網絡下面流量是很貴的。如果把原圖下載了下來,用戶也不看,這樣流量就浪費了,這浪費的就是錢,肯定不合適。那怎么辦呢?可以設計一個算法,類似于銀行家算法,給每個用戶分配一個配額。比如說有500K的配額,預拉取一張原圖,比如100K,如果用戶看了原圖,配額不變;如果用戶后來并沒有看,則把配額減去100K,凡是預拉取了而不看的配額都減掉,配額減到零就不會再做預拉取了,避免盲目下載造成大量的流量消耗。
在WIFI情況下,是不是可以簡單地全下載下來呢?這樣也不好。雖然用戶的流量在WIFI下基本不收費,但是騰訊后臺的出口帶寬很貴。尤其是圖片下載消耗非常大,這個錢是很多的。怎么辦呢?可以根據業(yè)務場景做細分。比如把圖片分為群圖和C2C圖,就是好友之間點對點的圖。分析發(fā)現,C2C圖相對是比較重要的,用戶點看原圖的概率非常大。同時C2C圖占比相對來說又是非常小的,因為大部分是群圖。所以C2C圖可以預拉取。群圖還是采用類似于銀行家算法的方式進行管控。
預拉取思路很簡單,但是要做好,可能還需要很細致地結合網絡狀況,結合用戶狀況和業(yè)務場景做細致全面的細分,這樣才能在用戶體驗,以及服務成本和用戶成本之間找到一個恰當的平衡。
信息繁簡不一。很多信息應該分類歸檔,針對一些好終端、好網絡,盡量返回一次很好的信息,反之只給它簡化版。
多種套圖規(guī)格。需要根據多種屏幕來抽象和簡化出幾種通用的圖片規(guī)格,而且可以根據不同網絡狀況來定每種規(guī)格的壓縮率。
終端是該輕還是重。到了手機時代,因為手機本身能力比較弱,而且產品還經常要求做一些跨終端的一致體驗,很多東西必須放在云端統(tǒng)一處理才可以。大部分場景下是輕終端重后臺,具體要看業(yè)務場景。比如說有些游戲,以前PC時代為了防止PC客戶端作弊,很多信息都是客戶端直接給server,一律由server統(tǒng)一去算。但是在手機游戲上面,為了減少信息傳遞以及減少交互次數,很可能會在終端也做適當的計算,把計算結果再發(fā)給server,在這種特殊的場景下面,在這些邏輯方面可能終端做的更重一些。所以這個問題有普遍性,也有特殊性,要具體分析、具體看,深入理解業(yè)務場景和邏輯。
能不差異的地方就不差異,考慮全面些。設計的時候要考慮全面,要把各種平臺、各種網絡都考慮到。在選擇壓縮算法、加密算法、圖片格式和文件格式時,這些東西能通用的還是盡量通用,不要給自己找麻煩。如果有些地方沒法統(tǒng)一,必須要差異,這里要抽象簡化,簡化為幾大類,而且這個差異點盡量使后臺可調可控。
終端版本信息管理,終端運營配置管理。需要把終端版本的各種信息記錄下來,然后才可以根據這些信息,再加上用戶的信息靈活調整配置給不同用戶更好的體驗??梢愿鶕煌貐^(qū)、不同網絡、不同版本、不同運營商和不同號碼,以及根據不同的CPU、不同的攝象頭、不同的內存,給用戶下發(fā)不同的閃屏和不同的插件,這是基礎能力的建設。
范瑞彬最后還用一句話做了總結:“從實踐中來,到實踐中去”。
本文演講者 范瑞彬
- 目前還沒評論,等你發(fā)揮!