天天看點

攜程App網絡服務通道治理和性能優化

App網絡服務的高可靠和低延遲對于無線業務穩定發展至關重要,過去兩年來我們一直在持續優化App網絡服務的性能,到今年Q2結束時基本完成了App網絡服務通道治理和性能優化的階段性目标,特此撰文總結其中的經驗教訓,為以後的工作打下基礎。

攜程App無線網絡服務架構

2014年攜程為無線服務開發了MobileGateway,有兩種類型:TCP Gateway和HTTP Gateway。 TCP Gateway設計用于App中Native業務網絡服務,基于TCP協定之上設計了應用層協定,類似于RPC機制。TCP Gateway兼具了接入層和服務動态路由的功能,接入層的功能基于Netty實作,管理用戶端的TCP長連接配接或者短連接配接;動态路由的功能基于Netfix開源的Zuul實作(Zuulis a gateway service that provides dynamic routing, monitoring, resiliency,security, and more.),可以在TCP Gateway上實作服務路由、監控、反爬和使用者鑒權等功能。

攜程App網絡服務通道治理和性能優化

TCP Gateway

每個TCP服務請求到達TCPGateway之後,會根據封包頭中的服務号,轉發到後端對應的業務服務叢集上,進而實作後端服務的解耦。TCPGateway到後端業務服務叢集之間的轉發使用HTTP協定的接口形式實作,一個TCP服務請求的完整封包會作為HTTP請求的Payload轉發到後端業務服務叢集,接收到HTTP響應後,會将其Payload完整的傳回到對應的TCP連接配接中。

HTTPGateway用于App中Hybrid和H5 Web站點的網絡服務,采用HTTP Restful接口形式提供服務,其邏輯相對簡單,核心是HTTP服務動态轉發的功能。

攜程App網絡服務通道治理和性能優化

HTTP Gateway

MobileGateway的更多設計實作細節可以參考王興朝同學在2015上海QCon的演講《攜程無線Gateway》。

基于TCP協定實作App網絡服務

帶寬和延遲是影響網絡服務性能的兩個因素,帶寬受網絡通道上最小帶寬的網段限制,延遲是網絡包在用戶端和服務端之間的來回傳輸時長,不同網絡類型上的帶寬和延遲差别非常大(見下圖)。

攜程App網絡服務通道治理和性能優化

帶寬和延遲

我們要實作更好性能的網絡服務,對于網絡自身的帶寬和延遲這兩點而言,能做隻是盡可能選擇最合适的網絡通道,其他隻能在如何使用網絡通道上進行優化。

傳統的非IM即時消息類App通常都是使用HTTP協定來實作網絡服務的(RestfulAPI形式),攜程使用TCP協定來實作,确實會增加很多開發成本,例如需要設計應用層協定、管理網絡連接配接、處理異常等,但下面幾點原因還是讓我們最終選擇基于TCP協定來實作App網絡服務:

1.攜程使用者有時會在網絡環境非常差的景區使用,需要針對弱網進行特别的優化,單純HTTP應用層協定很難實作。

2.HTTP請求首次需要進行DNS域名解析,我們發現國内環境下針對攜程域名的失敗率在2-3%(包含域名劫持和解析失敗的情況),嚴重影響使用者體驗。

3.HTTP雖然是基于TCP協定實作的應用層協定,優勢是封裝性好,用戶端和服務端解決方案成熟。劣勢是可控性小,無法針對網絡連接配接、發送請求和接收響應做定制性的優化,即使是HTTP的特性如保持長連接配接KeepAlive或者管道Pipeline等都會受制于網絡環境中的Proxy或者服務端實作,很難充分發揮作用。

基于TCP協定實作可以讓我們能夠完整控制整個網絡服務生命周期的各個階段,包括如下幾個階段:

1.擷取服務端IP位址

2.建立連接配接

3.序列化網絡請求封包

4.發送網絡請求

5.接受網絡響應

6.反序列化網絡響應封包

我們的網絡服務通道治理和優化工作就是從這幾個方面展開的。

TCP網絡服務通道治理和性能優化

1. 告别DNS,直接使用IP位址

如果是首次發送基于HTTP協定的網路服務,第一件事就是進行DNS域名解析,我們統計過DNS解析成功率隻有98%,剩下2%是解析失敗或者營運商DNS劫持(LocalDNS傳回了非源站IP位址),同時DNS解析在3G下耗時200毫秒左右,4G也有100毫秒左右,延遲明顯。我們基于TCP連接配接,直接跳過了DNS解析階段,使用内置IP清單的方式進行網絡連接配接。

攜程App内置了一組ServerIP清單,同時每個IP具備權重。每次建立新連接配接,會選擇權重最高的IP位址進行連接配接。App啟動時,IP清單的所有權重是相同的,此時會啟動一組Ping的操作,根據Ping值的延遲時間來計算IP的權重,這麼做的原理是Ping值越小的IP位址,連接配接後的網絡傳輸延遲也應該相對更小。業界也有使用HTTPDNS方式來解決DNS劫持問題,同時傳回最合适使用者網絡的ServerIP。然而HTTPDNS的開發和部署需要不小的開發成本,我們目前沒有使用。

内置ServerIP清單也會被更新,每次App啟動後會有個MobileConfig服務(支援TCP和HTTP兩種網絡類型服務)更新Server IP清單,同時支援不同産品線的Server IP清單更新。是以,傳統DNS解析能夠解決多IDC導流的功能也可以通過此方法解決。

2. Socket連接配接優化,減少連接配接時間

和HTTP協定中的Keepalive特性一樣,最直接減少網絡服務時間的優化手段就是保持長連接配接。每次TCP三向交握連接配接需要耗費用戶端和服務端各一個RTT(Roundtrip time)時間才能完成,就意味着100-300毫秒的延遲;TCP協定自身應對網絡擁塞的Slow Start機制也會影響新連接配接的傳輸性能。

攜程App使用了長連接配接池的方式來使用長連接配接,長連接配接池中維護了多個保持和服務端的TCP連接配接,每次網絡服務發起後會從長連接配接池中擷取一個空閑長連接配接,完成網絡服務後再将該TCP連接配接放回長連接配接池。我們沒有在單個TCP連接配接上實作Pipeline和Multiplexing機制,而是采用最簡單的FIFO機制,原因有二:1.簡化MobileGateway的服務處理邏輯,減少開發成本;2.在服務端同時傳回多個響應時,如果某個響應封包非常大,使用多個長連接配接方式可以加快接收服務響應封包速度。

如果發起網絡服務時長連接配接池中的TCP連接配接都正在被占用,或者TCP長連接配接的網絡服務失敗,則會發起一個TCP短連接配接實作網絡服務。這裡長連接配接和短連接配接的差別僅僅是服務完成後是否直接關閉這個TCP連接配接。

附:Pipeline和Multiplexing是有差別的,如HTTP/1.1支援Pipeline,用戶端能否同時發送多個請求,但是服務端傳回響應時也要按照請求的發送次序來傳回響應;SPDY和HTTP/2協定支援Multiplexing,即支援響應封包的亂序傳回,發送請求和接收響應互不幹擾,是以避免了HTTP/1.1Pipeline也沒能完全解決的Head of line blocking問題。參考資料:1,2。參考資曆2中提到HTTP/1.1的Pipeline特性隻是部分解決了Head of line blocking問題,因為a large orslow response can still block others behind it。

3. 弱網和網絡抖動優化

攜程App引入了網絡品質參數,通過網絡類型和端到端Ping值進行計算,根據不同的網絡品質改變網絡服務政策:

調整長連接配接池個數:例如在2G/2.5GEgde網絡下,會減少長連接配接池個數為1(營運商會限制單個目标IP的TCP連接配接個數);WIFI網絡下可以增加長連接配接池個數等機制。

動态調整TCPconnection、write、read的逾時時間。

網絡類型切換時,例如WIFI和移動網絡、4G/3G切換至2G時,用戶端IP位址會發生變化,已經連接配接上的TCPSocket注定已經失效(每個Socket對應一個四元組:源IP、源Port、目标IP、目标Port),此時會自動關閉所有空閑長連接配接,現有網絡服務也會根據狀态自動重試。

4. 資料格式優化,減少資料傳輸量和序列化時間

傳輸資料量越小,在相同TCP連接配接上的傳輸時間越短。攜程App曾經使用自行設計的一套資料格式,後來和GoogleProtocolBuffer對比後發現,特定資料類型下資料包大小會降低20-30%,序列化和反序列化時間可以降低10-20%,是以目前核心服務都在逐漸遷移到到ProtocolBuffer格式。另外Facebook曾分享過他們使用FlatBuffer資料格式提高性能的實踐,我們分析後不太适合攜程的業務場景因而沒有使用。

5. 引入重試機制,提升網絡服務成功率

受TCP協定重傳機制來保證可靠傳輸的機制啟發,我們在應用層面也引入了重試機制來提高網絡服務成功率。我們發現90%以上的的網絡服務失敗都是由于網絡連接配接失敗,此時再次重試是有機會連接配接成功并完成服務的;同時我們發現前面提到的網絡服務生命周期處于1建立連接配接、序列化網絡請求封包、發送網絡請求這三個階段失敗時,都是可以自動重試的,因為我們可以确信請求還沒有達到服務端進行處理,不會産生幂等性問題(如果存在幂等性問題,會出現重複訂單等情況)。當網絡服務需要重試時,會使用短連接配接進行補償,而不再使用長連接配接。

實作了上述機制後,攜程App網絡服務成功率由原先的95.3%+提升為如今的99.5%+(這裡的服務成功率是指端到端服務成功率,即用戶端采集的服務成功數除以請求總量計算的,并且不區分目前網絡狀況),效果顯著。

6. 其他網絡服務機制 & Tricks

攜程App也實作了其他一些網絡服務機制友善業務開發,如網絡服務優先級機制,高優先級服務優先使用長連接配接,低優先級服務預設使用短連接配接;網絡服務依賴機制,根據依賴關系自動發起或取消網絡服務,例如主服務失敗時,子服務自動取消。

開發過程中我們也發現一些移動平台上的TCPSocket開發tricks:

1.iOS平台上的原生Socket接口建立連接配接并不會激活移動網絡,這裡原生Socket接口是指POSIXSocket接口,必須使用CFSocket或者再上層的網絡接口嘗試網絡連接配接時才會激活網絡。是以攜程App啟動時會優先激活注冊一些第三方SDK以及發送HTTP請求來激活移動網絡。

2.合理設定Socket的幾個參數:SO_KEEPALIVE參數確定TCP連接配接保持(注:此KeepAlive是TCP中的屬性,和HTTP的KeepAlive是兩個場景概念),SO_NOSIGPIPE參數關閉SIGPIPE事件,TCP_NODELAY參數關閉TCPNagle算法的影響。

3.由于iOS要求支援IPv6-Only網絡,是以使用原生Socket必須支援IPv6。

4.如果使用select來處理nonblockingIO操作,確定正确處理不同的傳回值和逾時參數。

5.保持TCP長連接配接可用性的心跳機制:對于非IM類應用而言,心跳機制的作用不大,因為使用者會不斷觸發請求去使用TCP連接配接,尤其在攜程業務場景下,通過資料統計發現使用心跳與否對服務耗時和成功率影響極小,是以目前已經關閉心跳機制。原先的心跳機制是TCP長連接配接池中的空閑TCP連接配接每60秒發送一個心跳包到Gateway,Gateway傳回一個心跳響應包,進而讓雙方确認TCP連接配接有效。

Hybrid網絡服務優化

攜程App中有相當比例的業務是使用Hybrid技術實作的,運作在WebView環境中,其中的所有網絡服務(HTTP請求)都是由系統控制的,我們無法掌控,也就無法進行優化,其端到端服務成功率也僅有97%左右(注:這裡指頁面中業務邏輯發送的網絡服務請求,而非靜态資源請求)。

我們采用了名為『TCPTunnel for Hybrid』的技術方案來優化Hybrid網絡服務,和傳統HTTP加速産品的方法不同,我們沒有采用攔截HTTP請求再轉發的方式,而是在攜程Hybrid架構中的網絡服務層進行自動切換。

攜程App網絡服務通道治理和性能優化

TCP Tunnel for Hybrid

如圖所示,該技術方案的流程如下:

1.如果App支援TCPTunnel for Hybrid,Hybrid業務在發網絡服務時,會通過Hybrid接口轉發至App Native層的TCP網絡通訊層,該子產品會封裝這個HTTP請求,作為TCP網絡服務的Payload轉發到TCP Gateway;

2.TCP Gateway會根據服務号判斷出是Hybrid轉發服務,解包後将Payload直接轉發至HTTP Gateway,此HTTP請求對HTTP Gateway是透明的,HTTP Gateway無需區分是App直接發來的還是TCP Gateway轉發來的HTTP請求;

3.後端業務服務處理完成後,HTTP響應會經HTTPGateway傳回給TCP Gateway,TCP Gateway将此HTTP響應作為Payload傳回給App的TCP網絡通訊層;

4.TCP網絡通訊層會再将該Payload反序列化後傳回給Hybrid架構,最終異步回調給Hybrid業務調用方。整個過程對于Hybrid業務調用方也是透明的,它并不知道TCPTunnel的存在。

采用該技術方案後,攜程App中Hybrid業務的網絡服務成功率提升至99%以上,平均耗時下降了30%。

攜程App網絡服務通道治理和性能優化

TCP Tunnel for Hybrid Result

海外網絡服務優化

攜程目前沒有部署海外IDC,海外使用者在使用App時需要通路位于國内的IDC,服務平均耗時明顯高于國内使用者。我們采用了名為『TCPBypass for Oversea』的技術方案來優化海外網絡服務性能,主要是使用了Akamai的海外專屬網絡通道,同時在攜程國内IDC部署了局端裝置,使用專用加速通道的方式來提升海外使用者體驗。

攜程App網絡服務通道治理和性能優化

TCP Bypass for Oversea

海外使用者啟動App後先通過Akamai定制域名擷取ServerIP,所有網絡服務優先走Akamai通道;如果Akamai通道的網絡服務失敗并且重試機制生效時,會改走傳統Internet通道進行重試。相比隻用傳統Internet通道,在保持網絡服務成功率不變的情況下,使用Akamai通道Bypass技術後平均服務耗時下降了33%。

攜程App網絡服務通道治理和性能優化

TCP Bypass for Oversea Result

其他網絡協定探讨

過去兩年我們的網絡服務優化工作都是基于TCP協定實作的,基本達到了優化目标。不過這兩年來新的應用層網絡協定SPDY和HTTP/2逐漸邁入主流,基于UDP的QUIC協定看起來也非常有趣,值得跟進調研。

SPDY & HTTP/2

SPDY是Google基于TCP開發的網絡應用層協定,目前已經停止開發,轉向支援基于SPDY成果設計的HTTP/2協定,HTTP/2協定的核心改進其實就是針對HTTP/1.x中影響延遲性能的痛點進行優化:

1.Header壓縮:壓縮備援的HTTP請求和響應Header。

2.支援Multiplexing:支援一個TCP連接配接上同時實作多個請求和響應。

3.保持長連接配接(比HTTP/1.x更徹底):減少網絡連接配接時間。

4.支援推送:可以由服務端主動推送資料到用戶端。

官方性能測試結果顯示使用SPDY或者HTTP/2的頁面加載時間減少30%左右,不過這是針對網頁的測試結果,對于App中的網絡服務,具體優化效果我們還在進行内部測試,不過其優化手段看和目前我們使用TCP協定的優化手段類似,是以性能優化效果可能不會很顯著。

QUIC

QUIC是Google基于UDP開發的應用層協定,UDP協定無需連接配接,不存在重傳機制,是以應用層需要保證服務的可靠性。目前國内騰訊有針對弱網絡嘗試過QUIC協定,我們也在進行測試,最終是否會采用還需要看測試的結果。

綜述

技術隻是手段,最終還是要反映在業務效果上。我們已經實作除靜态資源等需要通路CDN的網絡請求外,其他App網絡服務使用統一的TCP通道,進而具備更好的性能調優和業務監控能力。攜程目前基于TCP協定的各種App網絡服務優化,也是各種技術方案的平衡,雖然目前HTTP/2等新協定逐漸成熟,但是TCP協定自身的靈活性支援有針對性的性能優化,還是具備其特别的優勢,希望我們的實踐總結能對國内無線技術從業者有一些借鑒價值。