您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶(hù)?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>通訊/手機(jī)編程>

實(shí)例分析攜程App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化

大?。?/span>0.6 MB 人氣: 2017-10-10 需要積分:1
App網(wǎng)絡(luò)服務(wù)的高可靠和低延遲對(duì)于無(wú)線(xiàn)業(yè)務(wù)穩(wěn)定發(fā)展至關(guān)重要,過(guò)去兩年來(lái)我們一直在持續(xù)優(yōu)化App網(wǎng)絡(luò)服務(wù)的性能,到今年Q2結(jié)束時(shí)基本完成了App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化的階段性目標(biāo),特此撰文總結(jié)其中的經(jīng)驗(yàn)教訓(xùn),為以后的工作打下基礎(chǔ)。
  一、攜程App無(wú)線(xiàn)網(wǎng)絡(luò)服務(wù)架構(gòu)
  2014年攜程為無(wú)線(xiàn)服務(wù)開(kāi)發(fā)了Mobile Gateway,有兩種類(lèi)型:TCP Gateway和HTTP Gateway。 TCP Gateway設(shè)計(jì)用于App中Native業(yè)務(wù)網(wǎng)絡(luò)服務(wù),基于TCP協(xié)議之上設(shè)計(jì)了應(yīng)用層協(xié)議,類(lèi)似于RPC機(jī)制。TCP Gateway兼具了接入層和服務(wù)動(dòng)態(tài)路由的功能,接入層的功能基于Netty實(shí)現(xiàn),管理客戶(hù)端的TCP長(zhǎng)連接或者短連接;動(dòng)態(tài)路由的功能基于Netfix開(kāi)源的Zuul實(shí)現(xiàn)(Zuul is a gateway service that provides dynamic routing, monitoring, resiliency, security, and more. ),可以在TCP Gateway上實(shí)現(xiàn)服務(wù)路由、監(jiān)控、反爬和用戶(hù)鑒權(quán)等功能。
  實(shí)例分析攜程App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化
  每個(gè)TCP服務(wù)請(qǐng)求到達(dá)TCP Gateway之后,會(huì)根據(jù)報(bào)文頭中的服務(wù)號(hào),轉(zhuǎn)發(fā)到后端對(duì)應(yīng)的業(yè)務(wù)服務(wù)集群上,從而實(shí)現(xiàn)后端服務(wù)的解耦。TCP Gateway到后端業(yè)務(wù)服務(wù)集群之間的轉(zhuǎn)發(fā)使用HTTP協(xié)議的接口形式實(shí)現(xiàn),一個(gè)TCP服務(wù)請(qǐng)求的完整報(bào)文會(huì)作為HTTP請(qǐng)求的Payload轉(zhuǎn)發(fā)到后端業(yè)務(wù)服務(wù)集群,接收到HTTP響應(yīng)后,會(huì)將其Payload完整的返回到對(duì)應(yīng)的TCP連接中。
  HTTP Gateway用于App中Hybrid和H5 Web站點(diǎn)的網(wǎng)絡(luò)服務(wù),采用HTTP Restful接口形式提供服務(wù),其邏輯相對(duì)簡(jiǎn)單,核心是HTTP服務(wù)動(dòng)態(tài)轉(zhuǎn)發(fā)的功能。
  實(shí)例分析攜程App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化
  Mobile Gateway的更多設(shè)計(jì)實(shí)現(xiàn)細(xì)節(jié)可以參考王興朝同學(xué)在2015上海QCon的演講《攜程無(wú)線(xiàn)Gateway》。
  二、基于TCP協(xié)議實(shí)現(xiàn)App網(wǎng)絡(luò)服務(wù)
  帶寬和延遲是影響網(wǎng)絡(luò)服務(wù)性能的兩個(gè)因素,帶寬受網(wǎng)絡(luò)通道上最小帶寬的網(wǎng)段限制,延遲是網(wǎng)絡(luò)包在客戶(hù)端和服務(wù)端之間的來(lái)回傳輸時(shí)長(zhǎng),不同網(wǎng)絡(luò)類(lèi)型上的帶寬和延遲差別非常大(見(jiàn)下圖)。
  實(shí)例分析攜程App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化
  我們要實(shí)現(xiàn)更好性能的網(wǎng)絡(luò)服務(wù),對(duì)于網(wǎng)絡(luò)自身的帶寬和延遲這兩點(diǎn)而言,能做只是盡可能選擇最合適的網(wǎng)絡(luò)通道,其他只能在如何使用網(wǎng)絡(luò)通道上進(jìn)行優(yōu)化。
  傳統(tǒng)的非IM即時(shí)消息類(lèi)App通常都是使用HTTP協(xié)議來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)的(Restful API形式),攜程使用TCP協(xié)議來(lái)實(shí)現(xiàn),確實(shí)會(huì)增加很多開(kāi)發(fā)成本,例如需要設(shè)計(jì)應(yīng)用層協(xié)議、管理網(wǎng)絡(luò)連接、處理異常等,但下面幾點(diǎn)原因還是讓我們最終選擇基于TCP協(xié)議來(lái)實(shí)現(xiàn)App網(wǎng)絡(luò)服務(wù):
  攜程用戶(hù)有時(shí)會(huì)在網(wǎng)絡(luò)環(huán)境非常差的景區(qū)使用,需要針對(duì)弱網(wǎng)進(jìn)行特別的優(yōu)化,單純HTTP應(yīng)用層協(xié)議很難實(shí)現(xiàn);
  HTTP請(qǐng)求首次需要進(jìn)行DNS域名解析,我們發(fā)現(xiàn)國(guó)內(nèi)環(huán)境下針對(duì)攜程域名的失敗率在2-3%(包含域名劫持和解析失敗的情況),嚴(yán)重影響用戶(hù)體驗(yàn);
  HTTP雖然是基于TCP協(xié)議實(shí)現(xiàn)的應(yīng)用層協(xié)議,優(yōu)勢(shì)是封裝性好,客戶(hù)端和服務(wù)端解決方案成熟。劣勢(shì)是可控性小,無(wú)法針對(duì)網(wǎng)絡(luò)連接、發(fā)送請(qǐng)求和接收響應(yīng)做定制性的優(yōu)化,即使是HTTP的特性如保持長(zhǎng)連接KeepAlive或者管道Pipeline等都會(huì)受制于網(wǎng)絡(luò)環(huán)境中的Proxy或者服務(wù)端實(shí)現(xiàn),很難充分發(fā)揮作用。
  基于TCP協(xié)議實(shí)現(xiàn)可以讓我們能夠完整控制整個(gè)網(wǎng)絡(luò)服務(wù)生命周期的各個(gè)階段,包括如下幾個(gè)階段:
  獲取服務(wù)端IP地址建立連接序列化網(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)文
  我們的網(wǎng)絡(luò)服務(wù)通道治理和優(yōu)化工作就是從這幾個(gè)方面展開(kāi)的。
  三、TCP網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化
  1. 告別DNS,直接使用IP地址
  如果是首次發(fā)送基于HTTP協(xié)議的網(wǎng)路服務(wù),第一件事就是進(jìn)行DNS域名解析,我們統(tǒng)計(jì)過(guò)DNS解析成功率只有98%,剩下2%是解析失敗或者運(yùn)營(yíng)商DNS劫持(Local DNS返回了非源站IP地址),同時(shí)DNS解析在3G下耗時(shí)200毫秒左右,4G也有100毫秒左右,延遲明顯。我們基于TCP連接,直接跳過(guò)了DNS解析階段,使用內(nèi)置IP列表的方式進(jìn)行網(wǎng)絡(luò)連接。
  攜程App內(nèi)置了一組Server IP列表,同時(shí)每個(gè)IP具備權(quán)重。每次建立新連接,會(huì)選擇權(quán)重最高的IP地址進(jìn)行連接。App啟動(dòng)時(shí),IP列表的所有權(quán)重是相同的,此時(shí)會(huì)啟動(dòng)一組Ping的操作,根據(jù)Ping值的延遲時(shí)間來(lái)計(jì)算IP的權(quán)重,這么做的原理是Ping值越小的IP地址,連接后的網(wǎng)絡(luò)傳輸延遲也應(yīng)該相對(duì)更小。業(yè)界也有使用HTTP DNS方式來(lái)解決DNS劫持問(wèn)題,同時(shí)返回最合適用戶(hù)網(wǎng)絡(luò)的Server IP。然而HTTP DNS的開(kāi)發(fā)和部署需要不小的開(kāi)發(fā)成本,我們目前沒(méi)有使用。
  內(nèi)置Server IP列表也會(huì)被更新,每次App啟動(dòng)后會(huì)有個(gè)Mobile Config服務(wù)(支持TCP和HTTP兩種網(wǎng)絡(luò)類(lèi)型服務(wù))更新Server IP列表,同時(shí)支持不同產(chǎn)品線(xiàn)的Server IP列表更新。因此,傳統(tǒng)DNS解析能夠解決多IDC導(dǎo)流的功能也可以通過(guò)此方法解決。
  2. Socket連接優(yōu)化,減少連接時(shí)間
  和HTTP協(xié)議中的Keepalive特性一樣,最直接減少網(wǎng)絡(luò)服務(wù)時(shí)間的優(yōu)化手段就是保持長(zhǎng)連接。每次TCP三次握手連接需要耗費(fèi)客戶(hù)端和服務(wù)端各一個(gè)RTT(Round trip time)時(shí)間才能完成,就意味著100-300毫秒的延遲;TCP協(xié)議自身應(yīng)對(duì)網(wǎng)絡(luò)擁塞的Slow Start機(jī)制也會(huì)影響新連接的傳輸性能。
  攜程App使用了長(zhǎng)連接池的方式來(lái)使用長(zhǎng)連接,長(zhǎng)連接池中維護(hù)了多個(gè)保持和服務(wù)端的TCP連接,每次網(wǎng)絡(luò)服務(wù)發(fā)起后會(huì)從長(zhǎng)連接池中獲取一個(gè)空閑長(zhǎng)連接,完成網(wǎng)絡(luò)服務(wù)后再將該TCP連接放回長(zhǎng)連接池。我們沒(méi)有在單個(gè)TCP連接上實(shí)現(xiàn)Pipeline和Multiplexing機(jī)制,而是采用最簡(jiǎn)單的FIFO機(jī)制,原因有二:1. 簡(jiǎn)化Mobile Gateway的服務(wù)處理邏輯,減少開(kāi)發(fā)成本;2. 在服務(wù)端同時(shí)返回多個(gè)響應(yīng)時(shí),如果某個(gè)響應(yīng)報(bào)文非常大,使用多個(gè)長(zhǎng)連接方式可以加快接收服務(wù)響應(yīng)報(bào)文速度。
  如果發(fā)起網(wǎng)絡(luò)服務(wù)時(shí)長(zhǎng)連接池中的TCP連接都正在被占用,或者TCP長(zhǎng)連接的網(wǎng)絡(luò)服務(wù)失敗,則會(huì)發(fā)起一個(gè)TCP短連接實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)。這里長(zhǎng)連接和短連接的區(qū)別僅僅是服務(wù)完成后是否直接關(guān)閉這個(gè)TCP連接。
  附:Pipeline和Multiplexing是有區(qū)別的,如HTTP/1.1支持Pipeline,客戶(hù)端能否同時(shí)發(fā)送多個(gè)請(qǐng)求,但是服務(wù)端返回響應(yīng)時(shí)也要按照請(qǐng)求的發(fā)送次序來(lái)返回響應(yīng);SPDY和HTTP/2協(xié)議支持Multiplexing,即支持響應(yīng)報(bào)文的亂序返回,發(fā)送請(qǐng)求和接收響應(yīng)互不干擾,因此避免了HTTP/1.1 Pipeline也沒(méi)能完全解決的Head of line blocking問(wèn)題。參考資料:1, 2。參考資歷2中提到HTTP/1.1的Pipeline特性只是部分解決了Head of line blocking問(wèn)題,因?yàn)閍 large or slow response can still block others behind it。
  3. 弱網(wǎng)和網(wǎng)絡(luò)抖動(dòng)優(yōu)化
  攜程App引入了網(wǎng)絡(luò)質(zhì)量參數(shù),通過(guò)網(wǎng)絡(luò)類(lèi)型和端到端Ping值進(jìn)行計(jì)算,根據(jù)不同的網(wǎng)絡(luò)質(zhì)量改變網(wǎng)絡(luò)服務(wù)策略:
  1) 調(diào)整長(zhǎng)連接池個(gè)數(shù):例如在2G/2.5G Egde網(wǎng)絡(luò)下,會(huì)減少長(zhǎng)連接池個(gè)數(shù)為1(運(yùn)營(yíng)商會(huì)限制單個(gè)目標(biāo)IP的TCP連接個(gè)數(shù));WIFI網(wǎng)絡(luò)下可以增加長(zhǎng)連接池個(gè)數(shù)等機(jī)制;
  2) 動(dòng)態(tài)調(diào)整TCP connection、write、read的超時(shí)時(shí)間;
  3) 網(wǎng)絡(luò)類(lèi)型切換時(shí),例如WIFI和移動(dòng)網(wǎng)絡(luò)、4G/3G切換至2G時(shí),客戶(hù)端IP地址會(huì)發(fā)生變化,已經(jīng)連接上的TCP Socket注定已經(jīng)失效(每個(gè)Socket對(duì)應(yīng)一個(gè)四元組:源IP、源Port、目標(biāo)IP、目標(biāo)Port),此時(shí)會(huì)自動(dòng)關(guān)閉所有空閑長(zhǎng)連接,現(xiàn)有網(wǎng)絡(luò)服務(wù)也會(huì)根據(jù)狀態(tài)自動(dòng)重試。
  4. 數(shù)據(jù)格式優(yōu)化,減少數(shù)據(jù)傳輸量和序列化時(shí)間
  傳輸數(shù)據(jù)量越小,在相同TCP連接上的傳輸時(shí)間越短。攜程App曾經(jīng)使用自行設(shè)計(jì)的一套數(shù)據(jù)格式,后來(lái)和Google ProtocolBuffer對(duì)比后發(fā)現(xiàn),特定數(shù)據(jù)類(lèi)型下數(shù)據(jù)包大小會(huì)降低20-30%,序列化和反序列化時(shí)間可以降低10-20%,因此目前核心服務(wù)都在逐步遷移到到ProtocolBuffer格式。另外Facebook曾分享過(guò)他們使用FlatBuffer數(shù)據(jù)格式提高性能的實(shí)踐,我們分析后不太適合攜程的業(yè)務(wù)場(chǎng)景因而沒(méi)有使用。
  5. 引入重試機(jī)制,提升網(wǎng)絡(luò)服務(wù)成功率
  受TCP協(xié)議重傳機(jī)制來(lái)保證可靠傳輸?shù)臋C(jī)制啟發(fā),我們?cè)趹?yīng)用層面也引入了重試機(jī)制來(lái)提高網(wǎng)絡(luò)服務(wù)成功率。我們發(fā)現(xiàn)90%以上的的網(wǎng)絡(luò)服務(wù)失敗都是由于網(wǎng)絡(luò)連接失敗,此時(shí)再次重試是有機(jī)會(huì)連接成功并完成服務(wù)的;同時(shí)我們發(fā)現(xiàn)前面提到的網(wǎng)絡(luò)服務(wù)生命周期處于1建立連接、序列化網(wǎng)絡(luò)請(qǐng)求報(bào)文、發(fā)送網(wǎng)絡(luò)請(qǐng)求這三個(gè)階段失敗時(shí),都是可以自動(dòng)重試的,因?yàn)槲覀兛梢源_信請(qǐng)求還沒(méi)有達(dá)到服務(wù)端進(jìn)行處理,不會(huì)產(chǎn)生冪等性問(wèn)題(如果存在冪等性問(wèn)題,會(huì)出現(xiàn)重復(fù)訂單等情況)。當(dāng)網(wǎng)絡(luò)服務(wù)需要重試時(shí),會(huì)使用短連接進(jìn)行補(bǔ)償,而不再使用長(zhǎng)連接。
  實(shí)現(xiàn)了上述機(jī)制后,攜程App網(wǎng)絡(luò)服務(wù)成功率由原先的95.3%+提升為如今的99.5%+(這里的服務(wù)成功率是指端到端服務(wù)成功率,即客戶(hù)端采集的服務(wù)成功數(shù)除以請(qǐng)求總量計(jì)算的,并且不區(qū)分當(dāng)前網(wǎng)絡(luò)狀況),效果顯著。
  6. 其他網(wǎng)絡(luò)服務(wù)機(jī)制 & Tricks
  攜程App也實(shí)現(xiàn)了其他一些網(wǎng)絡(luò)服務(wù)機(jī)制方便業(yè)務(wù)開(kāi)發(fā),如網(wǎng)絡(luò)服務(wù)優(yōu)先級(jí)機(jī)制,高優(yōu)先級(jí)服務(wù)優(yōu)先使用長(zhǎng)連接,低優(yōu)先級(jí)服務(wù)默認(rèn)使用短連接;網(wǎng)絡(luò)服務(wù)依賴(lài)機(jī)制,根據(jù)依賴(lài)關(guān)系自動(dòng)發(fā)起或取消網(wǎng)絡(luò)服務(wù),例如主服務(wù)失敗時(shí),子服務(wù)自動(dòng)取消。
  開(kāi)發(fā)過(guò)程中我們也發(fā)現(xiàn)一些移動(dòng)平臺(tái)上的TCP Socket開(kāi)發(fā)tricks:
  1) iOS平臺(tái)上的原生Socket接口創(chuàng)建連接并不會(huì)激活移動(dòng)網(wǎng)絡(luò),這里原生Socket接口是指POSIX Socket接口,必須使用CFSocket或者再上層的網(wǎng)絡(luò)接口嘗試網(wǎng)絡(luò)連接時(shí)才會(huì)激活網(wǎng)絡(luò)。因此攜程App啟動(dòng)時(shí)會(huì)優(yōu)先激活注冊(cè)一些第三方SDK以及發(fā)送HTTP請(qǐng)求來(lái)激活移動(dòng)網(wǎng)絡(luò);
  2) 合理設(shè)置Socket的幾個(gè)參數(shù):SOKEEPALIVE參數(shù)確保TCP連接保持(注:此KeepAlive是TCP中的屬性,和HTTP的KeepAlive是兩個(gè)場(chǎng)景概念),SONOSIGPIPE參數(shù)關(guān)閉SIGPIPE事件,TCP_NODELAY參數(shù)關(guān)閉TCP Nagle算法的影響;
  3) 由于iOS要求支持IPv6-Only網(wǎng)絡(luò),因此使用原生Socket必須支持IPv6;
  4) 如果使用select來(lái)處理nonblocking IO操作,確保正確處理不同的返回值和超時(shí)參數(shù);
  5) 保持TCP長(zhǎng)連接可用性的心跳機(jī)制:對(duì)于非IM類(lèi)應(yīng)用而言,心跳機(jī)制的作用不大,因?yàn)橛脩?hù)會(huì)不斷觸發(fā)請(qǐng)求去使用TCP連接,尤其在攜程業(yè)務(wù)場(chǎng)景下,通過(guò)數(shù)據(jù)統(tǒng)計(jì)發(fā)現(xiàn)使用心跳與否對(duì)服務(wù)耗時(shí)和成功率影響極小,因此目前已經(jīng)關(guān)閉心跳機(jī)制。原先的心跳機(jī)制是TCP長(zhǎng)連接池中的空閑TCP連接每60秒發(fā)送一個(gè)心跳包到Gateway,Gateway返回一個(gè)心跳響應(yīng)包,從而讓雙方確認(rèn)TCP連接有效。
  四、Hybrid網(wǎng)絡(luò)服務(wù)優(yōu)化
  攜程App中有相當(dāng)比例的業(yè)務(wù)是使用Hybrid技術(shù)實(shí)現(xiàn)的,運(yùn)行在WebView環(huán)境中,其中的所有網(wǎng)絡(luò)服務(wù)(HTTP請(qǐng)求)都是由系統(tǒng)控制的,我們無(wú)法掌控,也就無(wú)法進(jìn)行優(yōu)化,其端到端服務(wù)成功率也僅有97%左右(注:這里指頁(yè)面中業(yè)務(wù)邏輯發(fā)送的網(wǎng)絡(luò)服務(wù)請(qǐng)求,而非靜態(tài)資源請(qǐng)求)。
  我們采用了名為『TCP Tunnel for Hybrid』的技術(shù)方案來(lái)優(yōu)化Hybrid網(wǎng)絡(luò)服務(wù),和傳統(tǒng)HTTP加速產(chǎn)品的方法不同,我們沒(méi)有采用攔截HTTP請(qǐng)求再轉(zhuǎn)發(fā)的方式,而是在攜程Hybrid框架中的網(wǎng)絡(luò)服務(wù)層進(jìn)行自動(dòng)切換。

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

實(shí)例分析攜程App網(wǎng)絡(luò)服務(wù)通道治理和性能優(yōu)化下載

相關(guān)電子資料下載

      發(fā)表評(píng)論

      用戶(hù)評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?