攜程APP好用的秘訣大起底 告訴你APP性能優(yōu)化也有捷徑可走!
原創(chuàng)陳浩然,攜程負(fù)責(zé)無線基礎(chǔ)技術(shù)的高級開發(fā)總監(jiān)。在WOT2016移動互聯(lián)網(wǎng)技術(shù)峰會上,他與大家分享了攜程APP在網(wǎng)絡(luò)性能方面一些優(yōu)化實(shí)踐和方案。
攜程無線網(wǎng)絡(luò)服務(wù)通道架構(gòu)
陳浩然介紹了2016年年初攜程無線網(wǎng)絡(luò)服務(wù)通道的架構(gòu)圖,其中無線APP有兩個(gè)通道,一是Native,基于TCP設(shè)計(jì)的一套網(wǎng)絡(luò)服務(wù)通道,連了TCP Gateway;二是Hybrid,用GS寫界面,***是通過傳統(tǒng)的HTTP請求到達(dá)HTTP Gateway,TCP Gateway和HTTP Gateway最終鏈接到對應(yīng)的SOA服務(wù)。
陳浩然表示,APP端是通過TCP連接連到TCP Gateway,轉(zhuǎn)化后通過HTTP請求轉(zhuǎn)化到后端一個(gè)標(biāo)準(zhǔn)的SOA接口當(dāng)中,是一個(gè)標(biāo)準(zhǔn)的HTTP協(xié)議,前端通過TCP連接。
他在演講中表示,TCP協(xié)議是傳統(tǒng)協(xié)議,位于第三層,只控制網(wǎng)絡(luò)層的傳輸協(xié)議,到了應(yīng)用層還是需要設(shè)計(jì)一層應(yīng)用層協(xié)議,類似RPC機(jī)制。攜程的TCP Gateway分為兩個(gè)部分,***部分是在接入層管理TCP連接,主要基于Netty實(shí)現(xiàn),負(fù)責(zé)App端TCP連接管理。第二部分是在路由層,基于Netty Zuul對服務(wù)進(jìn)行路由、監(jiān)控、安全、鑒權(quán)方面的管理。“實(shí)現(xiàn)方式就是一個(gè)可插件式的中間件,不同插件實(shí)現(xiàn)不同功能,如路由、安全、鑒權(quán),數(shù)據(jù)格式***的是基于Protocol Buffers實(shí)現(xiàn)的。”
HTTP Gateway功能較為簡單,直接負(fù)責(zé)HTTP請求轉(zhuǎn)發(fā),路由層也是基于Zuul實(shí)現(xiàn),功能上和TCP Gateway非常接近,數(shù)據(jù)格式就是傳統(tǒng)JSON數(shù)據(jù)格式。
之所以需要Gateway,陳浩然解釋道,因?yàn)閿y程業(yè)務(wù)很多,目前有20多個(gè)事業(yè)部,每個(gè)事業(yè)部有自己的服務(wù)集群,如果將所有的服務(wù)集群耦合在一起,每個(gè)BU的發(fā)布都會影響到其他BU。而設(shè)置Gateway進(jìn)行服務(wù)轉(zhuǎn)化,后端所有業(yè)務(wù)邏輯是完全分割開來的,相應(yīng)的部署、發(fā)布、監(jiān)控都是完全割離開來的,這樣可以避免干擾,提升效率。
TCP與HTTP協(xié)議優(yōu)劣勢對比
談及為什么要基于TCP實(shí)現(xiàn)時(shí),陳浩然認(rèn)為,主要是與HTTP協(xié)議對比得出的結(jié)論。HTTP協(xié)議優(yōu)勢非常明顯,封裝性好,HTTP協(xié)議更標(biāo)準(zhǔn)化,客戶端和服務(wù)端解決方案相對成熟。但是劣勢在于可控性很差,受網(wǎng)絡(luò)影響嚴(yán)重,像HTTP1.1協(xié)議里的KeepAlive、Pipeline這些機(jī)制很難發(fā)揮作用。
而 TCP協(xié)議做網(wǎng)絡(luò)服務(wù),優(yōu)勢是可以針對網(wǎng)絡(luò)連接、發(fā)送請求和接受響應(yīng),不同階段可以完全分割很清楚,可以針對不同階段做定制性優(yōu)化。劣勢是實(shí)現(xiàn)很復(fù)雜,因?yàn)橐獙?shí)現(xiàn)自己的應(yīng)用層協(xié)議,開發(fā)成本和復(fù)雜度都比較高。
優(yōu)化APP網(wǎng)絡(luò)服務(wù)全生命周期
陳浩然表示,App對網(wǎng)絡(luò)環(huán)境要求較高,不同的網(wǎng)絡(luò)類型帶寬和延遲差別非常大,其中延遲對網(wǎng)絡(luò)性能影響***。雖然服務(wù)端做了很多優(yōu)化,但是如果網(wǎng)絡(luò)性能不佳,依然會帶來較大延遲,優(yōu)化效果不如在App端做優(yōu)化更好。
陳浩然將App網(wǎng)絡(luò)服務(wù)生命周期劃分為六個(gè)部分:一是DNS解析,二是建立連接,三是序列化網(wǎng)絡(luò)請求報(bào)文,四是發(fā)送網(wǎng)絡(luò)請求,五是接受網(wǎng)絡(luò)響應(yīng),六是反序列化網(wǎng)絡(luò)響應(yīng)報(bào)文。“攜程的做法是把生命周期每個(gè)步驟都進(jìn)行細(xì)化,針對每個(gè)階段進(jìn)行優(yōu)化。”
DNS解析的優(yōu)化
DNS解析階段有三個(gè)問題:一是解析有1%失敗概率,二是域名解析地址影響網(wǎng)絡(luò)服務(wù),三是解析耗時(shí)容易產(chǎn)生延遲。
DNS解析優(yōu)化有兩種解決方案:一種是自建HTTP-DNS,用IP地址訪問,發(fā)一個(gè)HTTP請求上來訪問DNS服務(wù)器,可以根據(jù)客戶端IP地址,告訴最合適服務(wù)端的IP地址是多少,但服務(wù)端開發(fā)部署成本比較高,而且***次還是要發(fā)HTTP-DNS服務(wù),前置服務(wù)帶來額外延遲。第二個(gè)解決方案是在App端內(nèi)置服務(wù)器IP列表,徹底取消DNS解析,但是客戶端如何能夠快速知道哪個(gè)服務(wù)端IP地址***,需要自行判斷。
攜程采取的解決方法是在App內(nèi)置服務(wù)IP列表,每個(gè)IP都有一個(gè)權(quán)重機(jī)制,會根據(jù)每次網(wǎng)絡(luò)服務(wù)選擇權(quán)重***的IP地址。IP權(quán)重如何計(jì)算?攜程在客戶端用Ping值,每個(gè)服務(wù)IP啟動之后立刻進(jìn)行Ping值,根據(jù)Ping值的延遲時(shí)間進(jìn)行計(jì)算,Ping值***的權(quán)重***,如果Ping不通可能是權(quán)重為零,最差的服務(wù)端地址。在網(wǎng)絡(luò)環(huán)境切換時(shí),IP權(quán)重會重新計(jì)算。
TCP連接的優(yōu)化
這方面優(yōu)化的重點(diǎn)是保持長連接。如果每次都建立連接整體耗時(shí)會非常大,用戶體驗(yàn)非常差。攜程的做法是配置一個(gè)TCP長連接池,專門用來存放長連接,根據(jù)網(wǎng)絡(luò)環(huán)境不同更新連接池大小的上線。每次網(wǎng)絡(luò)服務(wù)要發(fā)一個(gè)網(wǎng)絡(luò)請求,用戶點(diǎn)擊查詢,會優(yōu)先從長連接中拿出一個(gè)空閑長連接出來進(jìn)行網(wǎng)絡(luò)服務(wù),發(fā)完收到響應(yīng)一切都成功了,會再將空閑長連接放回到連接池當(dāng)中,等待下一次網(wǎng)絡(luò)服務(wù)發(fā)起。如果TCP長連接服務(wù)失敗,也會用短連接進(jìn)行重試,會有一些限制條件,實(shí)際上是長短結(jié)合的概念。為了簡單處理目前還沒有支持Pipeline或者是Multiplexing機(jī)制。
弱網(wǎng)和網(wǎng)絡(luò)抖動情況優(yōu)化
攜程會根據(jù)網(wǎng)絡(luò)類型以及端到端的Ping值進(jìn)行計(jì)算,首先將當(dāng)前網(wǎng)絡(luò)質(zhì)量劃分為好、中、差、非常差四類網(wǎng)絡(luò)質(zhì)量參數(shù),然后根據(jù)參數(shù)調(diào)整長連接個(gè)數(shù),在4G/WIFI會增加長連接池大小,目前長連接池是四個(gè)。其次根據(jù)網(wǎng)絡(luò)質(zhì)量參數(shù)調(diào)整TCP連接、發(fā)送請求,以及調(diào)整write或者read的超時(shí)時(shí)間。第三個(gè)方法是當(dāng)網(wǎng)絡(luò)類型切換時(shí),一旦客戶端IP變化,直接關(guān)閉所有長連接,現(xiàn)有正在發(fā)的網(wǎng)絡(luò)服務(wù)會進(jìn)行自動重試。
數(shù)據(jù)格式優(yōu)化
陳浩然表示,之前攜程App是使用自定義數(shù)據(jù)格式。后來調(diào)研了Protocol Buffers、Flat Buffers、Thrift這幾種比較常見的格式,最終選用了Protocol Buffers。在攜程特定的數(shù)據(jù)類型下,數(shù)據(jù)包大小可以降低,相對于之前的數(shù)據(jù)格式大小降低了20%-30%。序列化、反序列化時(shí)間也是可以降低10%-20%。如果大家自己開發(fā)這樣一個(gè)網(wǎng)絡(luò)協(xié)議,數(shù)據(jù)格式主要是考察兩點(diǎn):一個(gè)是數(shù)據(jù)包大小,一個(gè)是序列化和反序列化時(shí)間。數(shù)據(jù)包大小更重要,因?yàn)槿绻麛?shù)據(jù)包太小,網(wǎng)絡(luò)服務(wù)在傳輸過程中非常耗時(shí)。
“我的感觸主要有兩點(diǎn):一是盡量減少網(wǎng)絡(luò)連接時(shí)間,第二個(gè)盡量減少傳輸Size,盡量減少網(wǎng)絡(luò)帶寬和延遲的影響,延遲是必不可免的,帶寬是受限制的,數(shù)據(jù)量越小越好,同時(shí)也是連接越少越好。”陳浩然總結(jié)道。
他認(rèn)為選擇格式和自身業(yè)務(wù)類型相關(guān),F(xiàn)lat Buffers更適合于社交關(guān)系型數(shù)據(jù)存儲。而Thrift不單單是一個(gè)數(shù)據(jù)格式的解決方案,更多是IPC解決方案,包含了一個(gè)完整IPC解決方案。陳浩然告訴聽眾,F(xiàn)acebook的App就使用Flat Buffers,用于本地?cái)?shù)據(jù)Modle存儲。
網(wǎng)絡(luò)服務(wù)重試機(jī)制
攜程發(fā)現(xiàn)所有網(wǎng)絡(luò)服務(wù)失敗原因中有90%都是因?yàn)門CP連接失敗。連接失敗是否可以進(jìn)行重試?陳浩然認(rèn)為重試更多需要考慮可靠性問題,服務(wù)是否有冪等性問題,需要自己去解決。
攜程在這方面的經(jīng)驗(yàn)是如果在建立連接、序列化網(wǎng)絡(luò)請求報(bào)文,包括發(fā)送網(wǎng)絡(luò)請求這三個(gè)階段失敗,則直接進(jìn)行重試,并不需要業(yè)務(wù)程序來通知需要重試。另外也可以自行確保服務(wù)冪等性,添加重試參數(shù)。“攜程目前網(wǎng)絡(luò)服務(wù)成功率已經(jīng)從95.3%增長到99.5%。”陳浩然告訴聽眾。
Hybrid網(wǎng)絡(luò)性能優(yōu)化
傳統(tǒng)Hybrid網(wǎng)絡(luò)服務(wù)基于系統(tǒng)接口,無法控制網(wǎng)絡(luò)流程,平均網(wǎng)絡(luò)服務(wù)成功率僅為97%左右,攜程想了兩個(gè)方案:一是攔截所有HTTP請求進(jìn)行直接轉(zhuǎn)發(fā)。二是用Hybrid網(wǎng)絡(luò)接口方式進(jìn)行轉(zhuǎn)發(fā)。最終攜程選擇了第二個(gè)方案。
通過這張圖可以看出,發(fā)一個(gè)網(wǎng)絡(luò)請求是走Hybrid接口,由Native發(fā)一個(gè)TCP連接到TCP Gateway,并不知道TCP這個(gè)通道存在,還是正常發(fā)一個(gè)網(wǎng)絡(luò)請求,是Get還是Post,告訴Hybrid庫要發(fā)HTTP請求,以為還是HTTP請求,到Hybrid框架這一層,現(xiàn)在知道要發(fā)一個(gè)HTTP請求,把HTTP請求所有參數(shù)作為一個(gè)正常的TCP服務(wù),傳到TCP Gateway,這一層解析出服務(wù)號之后,其實(shí)要發(fā)HTTP請求,會拼接成一個(gè)正常的HTTP請求,再發(fā)到HTTP Gateway。對于HTTP Gateway而言,并不知道HTTP請求是從傳統(tǒng)Hybrid還是H5網(wǎng)站發(fā)來的HTTP請求,還是從TCP Gateway這一層發(fā)送的請求,對HTTP Gateway不需要做任何改造動作。只不過在HTTP端Hybrid網(wǎng)絡(luò)層和TCP Gateway做一些改造,這樣HTTP請求做一個(gè)通道的動作去做協(xié)議轉(zhuǎn)發(fā)。HTTP Gateway把包裝過的HTTP請求轉(zhuǎn)發(fā)到后端服務(wù)器之后,服務(wù)端響應(yīng)之后會把相應(yīng)HTTP響應(yīng)報(bào)文再傳給TCP Gateway,再會重新打包成一個(gè)正常攜程協(xié)議TCP響應(yīng)報(bào)文給客戶端,會再把這個(gè)報(bào)文解開,類似于把一個(gè)HTTP請求發(fā)送完了,得到響應(yīng)概念,再傳給Hybrid業(yè)務(wù)層。需要做的改造只是針對HTTP里Hybrid網(wǎng)絡(luò)發(fā)送接口需要進(jìn)行改造,包括TCP Gateway要加一個(gè)功能。對于業(yè)務(wù)端,傳統(tǒng)Hybrid業(yè)務(wù)層面開發(fā)者完全不需要知道這一層,HTTP Gateway也不需要這一層,對于業(yè)務(wù)來說是完全透明。
通過這樣的通道架構(gòu),所有HTTP請求都會通過TCP Gateway進(jìn)行中轉(zhuǎn),中轉(zhuǎn)到HTTP Gateway,對于業(yè)務(wù)是完全透明的,平均網(wǎng)絡(luò)服務(wù)成功率已經(jīng)提升到了99.2%,同時(shí)還把網(wǎng)絡(luò)服務(wù)耗時(shí)降低了30%。
海外網(wǎng)絡(luò)性能優(yōu)化
攜程在海外沒有IDC,除了CDN靜態(tài)資源之外,業(yè)務(wù)服務(wù)所有的請求都需要回源,速度非常慢。如何破?
攜程采用了Akamai(全球***的CDN廠商解決方案),有一個(gè)專署通道,到海外可以走Akamai專署通道,而不是傳統(tǒng)Internet路由線路到達(dá)服務(wù)端。如果海外用戶登錄,Akamai通過定制域名獲取服務(wù)端IP,之后所有網(wǎng)絡(luò)服務(wù)會優(yōu)先走Akamai通道,然后直接落地到攜程IDC,不需要再走傳統(tǒng)聯(lián)通、電信運(yùn)營商通道。當(dāng)然陳浩然也表示,Akamai通道不是***的,但平均耗時(shí)可以減少到30%,比傳統(tǒng)Internet通道優(yōu)化很多。
***的無線網(wǎng)絡(luò)服務(wù)通道架構(gòu)圖,不管Hybrid還是Native,都是走TCP連接做網(wǎng)絡(luò)服務(wù),Hybrid有一個(gè)內(nèi)部API來控制去發(fā)送網(wǎng)絡(luò)請求,不需要再讓系統(tǒng)來控制HTTP請求到HTTP Gateway,而只是全部用Native TCP連接到TCP Gateway,如果是Hybrid請求被包裝過了,就轉(zhuǎn)成HTTP請求到HTTP Gateway,如果是正常TCP請求就直接發(fā)送到對應(yīng)后端服務(wù),這是***的網(wǎng)絡(luò)服務(wù)通道。
本文由陳浩然于2016年8月,在WOT2016移動互聯(lián)網(wǎng)技術(shù)峰會性能專場《無線App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化》主題演講整理而成。WOT2016大數(shù)據(jù)峰會將于2016年11月25-26日在北京粵財(cái)JW萬豪酒店召開,屆時(shí),數(shù)十位大數(shù)據(jù)領(lǐng)域一線專家、數(shù)據(jù)技術(shù)先行者將齊聚現(xiàn)場,在圍繞機(jī)器學(xué)習(xí)、實(shí)時(shí)計(jì)算、系統(tǒng)架構(gòu)、NoSQL技術(shù)實(shí)踐等前沿技術(shù)話題展開深度交流和溝通探討的同時(shí),分享大數(shù)據(jù)領(lǐng)域***實(shí)踐和最熱門的行業(yè)應(yīng)用。了解WOT2016大數(shù)據(jù)技術(shù)峰會更多信息,請登陸大會官網(wǎng):http://wot.51cto.com/2016bigdata/