携程App的网络性能优化实践

原文:http://www.infoq.com/cn/articles/how-ctrip-improves-app-networking-performance#theCommentsSection算法

编者按:在4月23日~25日举行的QCon全球软件开发大会(北京站)上,携程无线开发总监陈浩然分享了《移动开发网络性能优化实践》,总结了携程在App网络性能优化方面的一些实践经验。在2014年接手携程无线App的框架和基础研发工做以后,陈浩然面对的首要工做就是App客户端性能优化,尤为是网络服务性能,这是全部App优化工做的重中之重。如下为正文。后端

首先介绍一下携程App的网络服务架构。因为携程业务众多,开发资源致使没法所有使用Native来实现业务逻辑,所以有至关一部分频道基于Hybrid实现。网络通信属于基础&业务框架层中基础设施的一部分,为App提供统一的网络服务:缓存

  • Native端的网络服务

Native模块是携程的核心业务模块(酒店、机票、火车票、攻略等),Native模块的网络服务主要经过TCP链接实现,而很是见的Restful HTTP API那种HTTP链接,只有少数轻量级服务使用HTTP接口做为补充。
TCP链接网络服务模块使用了长链接+短链接机制,即有一个长链接池保持必定数目长链接,用于减小每次服务额外的链接,服务完成后会将该链接Socket放回长链接池,继续保持链接状态(一段时间空闲后会被回收);短链接做为补充,每次服务完成后便会主动关闭链接。
TCP网络服务的Payload使用的是自定义的数据及序列化协议;HTTP服务的Payload比较简单,即常见的JSON数据格式。
性能优化

  • Hybrid端的网络服务

Hybrid模块因为是在WebView中展现本地或者直连的H5页面,页面逻辑发起的网络服务都是经过系统WebView的HTTP请求实现的。少许业务场景(须要加密和支付等)以Hybrid桥接接口形式的Native TCP通道来完成网络服务。服务器

下图是网络服务的部署架构图:网络

携程App全部网络服务,不管是TCP仍是HTTP都会先链接到一个API Gateway服务器。若是是TCP服务,会先链接上TCP Gateway,TCP Gateway会负责将请求经过HTTP转发到后端的SOA服务接口。HTTP Gateway的原理与之相似。TCP Gateway和HTTP Gateway的区别仅仅在客户端到服务端的链接方式不一样而已。Gateway的做用除了业务请求还有流量控制和熔断。架构

要发现常见网络性能问题,先来看看一个网络服务作了哪些事情:并发

1.DNS Lookupapp

2.TCP Handshake框架

3.TLS Handshake

4.TCP/HTTP Request/Response

首先会是DNS解析,而后TCP链接握手,TLS链接握手(若是有的话),链接成功后再发送TCP或HTTP请求以及收到响应。若是可以将这些过程逐一梳理并确保不会存在明显的性能问题,那么基本能够确保得到不错的网络性能。网络服务里有一个重要的性能标准,即 RTT(Round-Trip Time),往返时延,它表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便当即发送确认)所间隔的时间。理想状况下能够假设 4G网络RTT为100ms,3G网络RTT为200ms,很容易就能计算出咱们的App网络服务耗时的下限,固然还要加上服务器处理时间。

常见的网络性能问题有以下几种:

  • 问题一:DNS问题

DNS出问题的几率其实比你们感受的要大,首先是DNS被劫持或者失效,2015年初业内比较知名的就有Apple内部 DNS问题致使App Store、iTunes Connect帐户没法登陆;京东由于CDN域名付费问题致使服务停摆。携程在去年11月也遇到过DNS问题,主域名被国外服务商误列入黑名单,致使主站和H5等全部站点没法访问,可是App客户端的Native服务都正常,缘由后面介绍。

另外一个常见问题就是DNS解析慢或者失败,例如国内中国运营商网络的DNS就很慢,一次DNS查询的耗时甚至都能遇上一次链接的耗时,尤为2G网络状况下,DNS解析失败是很常见的。所以若是直接使用DNS,对于首次网络服务请求耗时和总体服务成功率都有很是大的影响。

  • 问题二:TCP链接问题

DNS成功后拿到IP,即可以发起TCP链接。HTTP协议的网络层也是TCP链接,所以TCP链接的成功和耗时也成为网络性能的一个因素。咱们发现常见的问题有TCP端口被封(例如上海长宽对非HTTP常见端口80、8080、443的封锁),以及TCP链接超时时长问题。端口被封,直接致使没法链接;链接超时时长太短,在低速网络上可能老是没法链接成果;链接超时过长,又有可能致使用户长时间等待,用户体验差。不少时候尽快失败从新发起一次链接会很快,这也是移动网络带宽不稳定状况下的一个常见状况。

  • 问题三:Write/Read问题

DNS Lookup和TCP链接成功后,就会开始发送Request,服务端处理后返回Response,若是是HTTP链接,业内大部分App是使用第三方 SDK或者系统提供的API来实现,那么只能设置些缓存策略和超时时间。iOS上的NSURLConnection超时时间在不一样版本上还有不一样的定义,不少时候须要本身设置Timer来实现;若是是直接使用TCP链接实现网络服务,就要本身对读写超时时间负责,与网络链接超时时长参数相似,过小了在低速网络很容易读写失败,太大了又可能影响用户体验,所以须要很是当心地处理。

咱们还遇到另外一类问题,某些酒店Wi-Fi对使用非80、8080和443等常见HTTP端口的服务进行了限制,即便发送Request是正常的,服务端可以正常收到,可是Response却被酒店网络proxy或防火墙拦截,客户端最终会等待读取超时。

移动网络和传统网络另外一个很大的区别是Connection Migration问题。定义一个Socket链接是四元组(客户端IP,客户端Port,服务端IP,服务端Port),当用户的网络在WIFI/4G /3G/2G类型中切换时,其客户端IP会发生变化,若是此时正在进行网络服务通信,那么Socket链接自身已经失效,最终也会致使网络服务失败。

  • 问题四:传输Payload过大

传的多就传的慢,若是没作过特别优化,传输Payload可能会比实际所须要的大不少,那么对于总体网络服务耗时影响很是大。

  • 问题五:复杂的国内外网络状况

国内运营商互联和海外访问国内带宽低传输慢的问题也使人难很是头疼。

看下携程App用户的网络类型分布:

Wi-Fi用户占比已超过60%,4G用户量正接近3G用户量,2G用户在逐步减小,用户的网络愈来愈好。4G/3G/2G网络的带宽和延迟差异很大,而带宽和延迟是网络性能的重要指标:

针对携程App用户的网络带宽和延迟,咱们采样了海内外各8个城市的数据:

注意网络带宽和延迟并无直接相关性,带宽高不意味着延迟低,延迟再低也不可能快过光速。从上图咱们能够看到海内外带宽相差很大,可是延迟基本一致。

针对上面这些问题,在网络复杂环境和国内运营商互通情况无能为力的状况下,就针对性地逐一优化,以期达到目标:连得上、连得快、传输时间短。

  • 优化实践一:优化DNS解析和缓存

因为咱们的App网络服务主要基于TCP链接,为了将DNS时间降至最低,咱们内置了Server IP列表,该列表能够在App启动服务中下发更新。App启动后的首次网络服务会从Server IP列表中取一个IP地址进行TCP链接,同时DNS解析会并行进行,DNS成功后,会返回最适合用户网络的Server IP,那么这个Server IP会被加入到Server IP列表中被优先使用。

Server IP列表是有权重机制的,DNS解析返回的IP很明显具备最高的权重,每次从Server IP列表中取IP会取权重最高的IP。列表中IP权重也是动态更新的,根据链接或者服务的成功失败来动态调整,这样即便DNS解析失败,用户在使用一段时间后也会选取到适合的Server IP。

  • 优化实践二:网络质量检测(根据网络质量来改变策略)

针对网络链接和读写操做的超时时间,咱们提出了网络质量检测机制。目前作到的是根据用户是在2G/3G/4G/Wi-Fi的网络环境来设置不一样的超时参数,以及网络服务的并发数量。2G/3G/4G网络环境对并发TCP链接的数量是有限制的(2G网络下运营商常常只能容许单个Host一个TCP链接),所以网络服务重要参数可以根据网络质量情况来动态设定对性能和体验都很是重要。

不过目前携程App网络00质量检测的粒度还比较粗,咱们正在作的优化就是可以测算到用户当前的网络RTT,根据RTT 值来设置参数,那会更加准确。Facebook App的作法是HTTP网络服务在HTTP Response的Header中下发了预估的RTT值,客户端根据这个RTT值便可以设计不一样的产品和服务策略。

  • 优化实践三:提供网络服务优先级和依赖机制

因为网络对并发TCP链接的限制,就须要可以控制没必要要的网络服务数量,所以咱们在通信模块中加入了网络服务优先级和依赖机制。发送一个网络服务,能够设置它的优先级,高优先级的服务优先使用长链接, 低优先级的就是用短链接。长链接因为是从长链接池中取到的TCP链接,所以节省了TCP链接时间。

网络服务依赖机制是指能够设置数个服务的依赖关系,即主从服务。假设一个App页面要发多个服务,主服务成功的状况下,才去发子服务,若是主服务失败了,自服务就无需再关心成功或者失败,会直接被取消。若是主服务成功了,那么子服务就会自动触发。

  • 优化实践四:提供网络服务重发机制

移动网络不稳定,若是一次网络服务失败,就马上反馈给用户你失败了,体验并不友好。咱们提供了网络服务重发机制,即当网络服务在链接失败、写Request失败、读Response失败时自动重发服务;长链接失败时就用短链接来作重发补偿,短链接服务失败时固然仍是用短链接来补偿。这种机制增长了用户体验到的服务成功几率。

固然不是全部网络服务均可以重发,例如当下订单服务在读取Response失败时,就不能重发,由于下单请求可能已经到达服务器,此时重发服务可能会形成重复订单,因此咱们添加了重发服务开关,业务段能够自行控制是否须要。

  • 优化实践五:减小数据传输量

咱们优化了TCP服务Payload数据的格式和序列化/反序列化算法,从自定义格式转换到了Protocol Buffer数据格式,效果很是明显。序列化/反序列算法也作了调整,若是你们使用JSON数据格式,选用一个高效的反序列化算法,针对真实业务数据进行测试,收益明显。
图片格式优化在业界已有成熟的方案,例如Facebook使用的WebP图片格式,已经被国内众多App使用。

  • 优化实践六:优化海外网络性能

海外网络性能的优化手段主要是经过花钱,例如CDN加速,提升带宽,实现动静资源分离,对于App中的Hybrid模块优化效果很是明显。

通过上面的优化手段,携程App的网络性能从优化之初的V5.9版本到如今V6.4版本,服务成功率已经有了大幅提高,核心服务成功率都在99%以上。注意这是客户端采集的服务成功率,即用户感知到的网络服务成功率,失败量中包含了客户端无网络和服务端的错误。网络服务平均耗时降低了150-200ms。咱们的目标是除2G网络外,核心业务的网络服务成功率都可以达到三个九。

数据格式优化的效果尤为明显,采用新的Protocol Buffer数据格式+Gzip压缩后的Payload大小下降了15%-45%。数据序列化耗时降低了80%-90%。

经历了这半年的网络性能优化,体会最深的就是Logging基础设施的重要性。若是咱们没有完整端到端监控和统计的能力,性能优化只能是盲人摸象。Logging基础设施须要包括客户端埋点采集、服务端T+0处理、后期分析、Portal展现、自动告警等多种功能,这也不是单纯的客户端框架团队能够完成的,而须要公司多个部门合做完成。

携程基于Elastic Search开发了网络实时监控Portal,可以实时监控全部的网络服务,包括多种维度,能够跟踪到单个目标用户的全部网络请求信息。
用户的性能数据都被喷到Haddop和Hive大数据平台,咱们能够轻松制定并分析网络性能KPI,例如服务成功率、服务耗时、链接成功率和链接耗时等,咱们作到了在时间、网络类型、城市、长短链接、服务号等多纬度的分析。下图是咱们的网络性能KPI Portal,能够查看任一服务的成功率,服务耗时、操做系统、版本等各类信息,对于某个服务的性能分析很是有用。

最后看看业界网络性能优化的新技术方向,目前最有潜力的是Google推出的SPDY和QUIC协议。

SPDY已成为HTTP/2.0 Draft,有但愿成为将来HTTP协议的新标准。HTTP/2.0提供了不少诱人的特性(多路复用、请求优先级、支持服务端推送、压缩HTTP Header、强制SSL传输、对服务端程序透明等)。国内不少App包括美团、淘宝、支付宝都已经在尝试使用SPDY协议,Twitter的性能测试代表能够下降30%的网络延迟,携程也作了性能测试,因为和TCP性能差距不明显,暂未在生产上使用。

QUIC是基于UDP实现的新网络协议,因为TCP协议实现已经内置在操做系统和路由器内核中,Google没法直接改进TCP,所以基于无链接的UDP协议来设计全新协议能够得到不少好处。首先可以大幅减小链接时间,QUIC能够在发送数据前只须要0 RTT时间,而传统TCP/TLS链接至少须要1-3 RTT时间才能完成链接(即便采用Fast-Open TCP或TLS Snapshot);其次能够解决TCP Head-of-Line Blocking问题,一般前一个TCP Packet发送成功前会拥塞后面的Packet发送,而QUIC能够避免这样的问题;QUIC也有更好的移动网络环境下拥塞控制算法;新的链接方式也大幅减小了Connectiont Migration问题的影响。

随着这些新协议的逐渐成熟,相信将来可以进一步提升移动端的网络服务性能,值得你们保持关注。

相关文章
相关标签/搜索