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