淘宝网前台应用性能优化实践

本文曾发表于2013年4月的《程序员》杂志前端

近年来,随着用户数和PV的增长,淘宝网的后端服务器数量增加很快;而且咱们知道,Web页面延迟时间和转化率之间有着直接的关联。出于提高系统吞吐量、下降成本、减小页面延迟、提高用户浏览体验、提升交易转化率的考虑,淘宝网在性能优化领域作了不少尝试。本文将从应用性能分析、基础设施优化、应用自身优化、前端性能优化这四个方面,对淘宝网的优化尝试作一个总结。ios

  • 应用性能分析程序员

  1. 1.前台应用介绍web

淘宝网前台应用是指商品详情、店铺、购物车等买家直接能够看到和使用的应用,这类应用PV较高,服务器数量较多。从技术实现来讲,淘宝前台应用都使用Velocity模板引擎渲染HTML,页面平均大小大于100KB,WebServer不保存数据,数据来自于后端的DB、RPC服务、消息中间件、Tair、SearchEngine、TFS等外部系统,除了写日志、读取配置和共通模板,磁盘读写不多,而相对于后端系统来讲可处理的最大吞吐量较低,单台虚拟机平均TPS不到200。根据分析,这些应用都属于CPU密集型应用。编程

  1. 2.度量关键指标后端

优化工做开始前,要先给系统作次体检,拿到关键指标,而后针对关键指标进行优化,这样在优化工做完成后,更容易度量成果。关键指标有吞吐量、页面大小、响应时间和每请求内存数。
A.吞吐量
经过线上环境单机压测,能够获得服务器预设最大负载状况下,应用单机的最高真实吞吐量。线上压测的方法有两种:对于全部HTTP请求都具有幂等性的系统,可使用开源的AB、http_load等工具,回放前一天的流量给服务器,逐渐增长压力,当系统负载达到预设值时就获得了应用当前最高吞吐量;对于全部HTTP请求不彻底具有幂等性的系统,能够采用Nginx引流的方式,将其余服务器的流量引到同一台服务器,以达到增长负载、获得最高吞吐量的目的。
B.页面大小、响应时间
页面大小和HTTP请求响应时间能够经过分析服务器访问日志获得。
C.每请求内存数
淘宝前台应用都是Java应用,内存使用较多,垃圾回收很容易成为瓶颈,因此设定这一指标来衡量应用的内存使用状况。每请求内存数的计算方法是:JVM单位时间内申请的内存/服务器单位时间内处理的请求数。
数组

  1. 3.查找应用瓶颈浏览器

瓶颈是系统中比较慢的部分,在瓶颈完成前其余部分须要等待,因此优化工做能够从分析瓶颈开始;应用代码的执行也符合2/8原则,即20%的代码执行会消耗80%的资源,找到这20%的代码去作优化才会有效果。自底向上,查找应用瓶颈能够分为下面几个部分:
A.系统瓶颈
使用top、sar、vmstat、mpstat、iostat等系统工具、JDK源生工具去分析CPU、IO、Memory在压测时的表现,关注当前进程的Thread、锁、打开File数、Socket数、GC表现等状况,看哪一块存在问题或者会先成为瓶颈;对于关键代码,使用Perf等工具查看热点和CPU缓存命中率。通过分析,CPU计算的通用瓶颈在字符串的查找、拼接、替换,字符字节的编码、解码转换,压缩、解压缩操做,外部调用的瓶颈在IO开销、序列化和反序列化操做。
B.代码瓶颈
对于运行态的Java代码,业界有不少工具能够用来查找瓶颈,好比收费的JProfiler、YourKit等,免费的TPTP、NetBeansProfiler、VisualVM等,咱们使用淘宝开发的适合线上运行的TProfiler工具(已开源),同时支持剖析和采样两种方式,能够获得对象建立排行和Java代码执行次数、执行时间排行。排在前边的热点代码,极有可能就是代码瓶颈所在,以下表所示:缓存

方法信息 执行时间 执行次数 总时间
com/xxx/web/core/NewList:execute() 61 3102 190067
com/xxx/web/core/PerformScreen:performScreen() 18 4822 87822
com/xxx/core/DefaultSearchAuction:doMultiSearch() 43 708 30357
com/xxx/core/DefaultSearchCatManager:doSearch() 4 1248 4552

C.模块瓶颈
基于前边的热点代码排行数据按模块作归类统计,能够得出每个模块的CPU资源消耗比重,以下图所示:性能优化

131322661.png

这样就能够得出:Velocity模板引擎是此应用的瓶颈模块,须要着重优化。

  • 基础设施优化

  1. 1.软件升级

淘宝以前的Web应用构建在Apache+mod_jk+JBoss4之上,软件栈相对陈旧,新版本的特性和优化也没法利用。作了一次大的升级后,变成如今的Tengine+Tomcat7,在一些应用上实测吞吐量有近10%的提升,也验证了Nginx使用epollIO模型带来的优越性能。操做系统由原来的32位升级为64位,可识别的内存变大,增长内存后调大新生代堆大小4倍,某应用吞吐量提高达到70%,可见新生代大小对应用吞吐量很是的重要;淘宝有专门的JVM团队和Linux内核团队,使用taobao-jdk(补丁开源)、淘宝内核、开启JVM大内存页后实测,某应用吞吐量提高40%;TCP初始拥塞窗口调优,对用户平均下载时间也有不错的提高。在当前开源软件百花齐放的形势下,升级基础软件投入不大,却能给系统性能带来较大提高,很是划算。惟一要面对的问题是升级周期会比较长,由于线上环境须要长时间的beta以保证新软件的稳定。

  1. 2.JVM调优

根据前面的分析和实践,吞吐量与GC有直接的关系,在页面大小不变的状况下,调大新生代有益于提高吞吐量,减少页面大小(每请求内存数)也能提高吞吐量。目前JDK7已经发布,但G1垃圾回收器还在开发中,通过咱们测试在GC表现上G1没有比CMS更好,因此目前仍是选择响应时间优先的CMS垃圾回收器。咱们的JVM部分行为参数和性能参数以下:

-Xms4g-Xmx4g-XX:PermSize=256m-XX:MaxPermSize=256m-Xmn2000m-XX:SurvivorRatio=10-XX:+UseConcMarkSweepGC-XX:+UseCMSCompactAtFullCollection-XX:+CMSParallelRemarkEnabled-XX:+CMSPermGenSweepingEnabled-XX:+CMSClassUnloadingEnabled-XX:+UseCMSInitiatingOccupancyOnly-XX:CMSInitiatingOccupancyFraction=82

除了基本的配置还能够作一些参数调优,好比在6u23以后默认开启的压缩指针,随着JDK7发布带来的分层编译、大内存页、逃逸分析等很是值得尝试的优化。除了参数调优,应用代码自己也能够调整,使其对GC更友好。在CMS垃圾回收机制下,MinorGC时业务线程会暂停25ms左右,MajorGC时业务线程会暂停500ms左右。用户的请求被暂停500ms是不能接受的,因此优化原则就是减小MajorGC,也就是减小Young区晋升到Tenured区的对象数。能够经过JVM源生工具jstat观察JVM各个分区间对象的迁移状况,而后合理分配堆每个分区的大小、调整TenuringThreshold阀值。应用对象管理要尽量缩短对象生命周期或尽量少建立新对象,减小页面模板大小也是一个可行的办法。咱们开发了TBJMap工具(已开源),能够分析JVM堆每个分区里都有哪些内容,这对于优化应用代码很是具备参考价值。JVM性能表现的最佳状态是没有MajorGC,在淘宝有些应用已经作到了这点。

  1. 3.二方包优化

每个工程都依赖不少jar包,这些jar包若是用的比较频繁对性能的影响相当重要,对二方包的优化不会随着业务代码的改变而性能降低,能够说一次优化永久受益。二方包优化有两个建议:能够作一次的工做不作屡次,在beancopy的场景下使用CGLib代替BeanUtils,性能有超过20倍的提高;能够提早作的工做提早作,IP库二方包优化过程当中把不少冗余操做提早处理掉,性能有接近1倍的提高。在技术选型时能够针对场景选择更优的二方包,好比LMAX-Exchange开源的高性能并发框架Disruptor。另外,若是改变了原来的二方包,代码不能提交回主干,未来会遇到版本升级困难的问题。

  1. 4.模板引擎优化

经过前面的分析可知,Velocity模板渲染是最大的模块瓶颈,除了减少模板大小,还能够从模板框架优化下手。由于Velocity是解释型语言,性能相对较差;执行过程当中还有大量的反射调用,效率可想而知;字符字节的转换也尤为消耗CPU。淘宝基于Velocity开发了语法兼容的Sketch框架,将Velocity模板编译成Java类执行,减小了反射调用,内部用字节存储页面,节约了从渲染到输出的两次编码转换。使用Sketch框架之后,不少应用总体吞吐量有超过20%的提高。另外,淘宝Sketch框架将于今年开源。

应用自身优化
  1. 1.压缩模板大小

在不少系统中,模板大小和吞吐量成反比,若是能大幅减少模板和HTML的大小,会给吞吐量带来很大提高。最简单的减少模板方法,就是删除空行和多余空格。对于URL比较多的页面,去掉“http:”这五个可省略的字符、长URL压缩、用URL别名代替全连接均可以带来不错的效果。若是for循环里重复数据较多,能够把数据移到for循环以外,屡次出现的只渲染一次,浏览器端渲染时再经过前端代码把重复内容放回去,这种业务上的去重,每每能带来很好的优化效果。

  1. 2.设置最佳并发

并发用户数、资源利用率、吞吐量和响应时间的关系能够参考下图:

131350194.png

当服务器处于低负载区,随着并发用户数的增长,资源利用率和吞吐量直线上升,响应时间没有明显的变化;当服务器处于高负载区,随着并发用户数的增长,资源利用率趋于饱和,吞吐量达到最高点后开始降低,响应时间开始有明显的增长;这时并发用户数继续增长,服务器则处于假死状态,资源利用率继续趋于饱和,吞吐量开始急剧降低,响应时间开始急剧上升,直到系统不能处理任何请求,咱们称之为服务器Down机。从这张图里咱们能够得出,服务器吞吐量最大的时候对应的并发用户数,就是这个服务器的最佳并发数,当并发用户数大于这个值的时候,系统服务能力开始明显降低,作优化要找到这个最佳并发数,经过稳定性模块设置到系统中,稳定性模块能够对超过最佳并发数的请求进行限流,以保证系统达到最好的性能表现,不会由于大流量冲击而垮掉。咱们通常经过线上压测来肯定系统最佳并发数,对于CPU密集型应用也能够用以下公式计算:

最佳并发=((CPU时间+CPU等待时间)/CPU时间)*CPU核数

  1. 3.代码瓶颈优化

前面介绍了如何找到影响性能的瓶颈代码,能够针对代码瓶颈进行优化。举个例子,通过分析发现某系统每一个请求都抛异常吞异常,致使服务器资源利用率上不去,吞吐量不高,修正后CPU使用率提升30%,系统吞吐量也提高近30%。抛JDK默认的异常比较影响性能,尤为是在线程调用栈很深的状况下,有的系统还使用异常做业务流程控制,有的异常直接被吞掉,危害都很大。taobao-jdk开发了异常监测功能,从JVM层面直接发现和暴露全部异常问题,杜绝了这一类瓶颈的出现。

  1. 4.外部调用优化

淘宝系统目前处于第三代分布式架构,为了优化外部调用,开发了并行RPC、并行搜索等功能,对于适合的场景能够有效下降响应时间。某些场景使用更优的ProtocolBuffers序列化框架,在某些对性能要求很高的场景,使用开发成本稍大、比ProtocolBuffers还快20%的Kryo框架。

  1. 5.面向CPU编程

对于CPU密集型应用,若是能减小CPU的使用则能够直接提高系统吞吐量。针对Web应用能够调低GZip压缩级别来下降HTTPServer对CPU的消耗。针对核心代码能够面向CPU编程:常常一块儿使用的Field能够放在一块儿,这样对CPU缓存比较友好;在多核服务器上对性能要求比较高的场景,能够补齐缓存行以减小伪共享的发生;按行处理不要按列处理数组,编写符合空间局部性的代码能够很好地提高性能;使用源生批量接口处理数组,这样一条CPU指令就能够完成操做;使用乐观策略(CAS)来代替同步和锁也能够有效提高性能。

  1. 6.架构优化

架构调整每每要对系统伤筋动骨,开发周期很长,但却能够带来最好的优化效果。列举几个咱们经常使用的架构优化方法:动态资源静态化,把须要服务器动态生成、更新不频繁的内容CDN化,内容变化了能够回源更新CDN,这样大幅减小了服务器的动态内容输出;后台依赖前台化,给后端服务暴露对外的HTTP接口,使服务器依赖转变成JS依赖,能够提高后端性能,而且把强依赖变成弱依赖,提高整个系统的稳定性;后端渲染前端化,对于数据远小于面,页面布局比较规则的场景适用;DB依赖缓存化,这点业界用的很是之多;善用缓存,针对不一样的场景能够缓存对象、缓存页面片断、缓存整个页面、缓存HTTP响应,使用缓存须要关注失效机制和数据预热,并尽量提升缓存命中率。

  • 前端性能优化

  1. 1.度量关键指标

咱们能够经过前端埋点和NavigationTiming接口来采集网页在用户浏览器上的关键指标,包括DNS查询时间、TCP链接创建时间、HTTP请求时间、页面下载时间、开始渲染时间、domReady、可交互时间、onLoad时间,使用阿里度等工具能够获得首屏时间。有了这些指标就能够衡量前端优化的效果。业界还有一些工具会给出不少优化建议,好比dynaTraceAJAXEdition、YSlow、Chrome插件SpeedTracer等,淘宝也根据Yahoo的34条军规,开发了本身的TSlow。

  1. 2.前端性能优化

Yahoo34条军规已经成为前端WPO的标准,这里再也不介绍。列几个对咱们的场景比较适用的优化:减少Cookie大小;减小DNS查询并适当增长不一样域名以优化资源并发加载;针对浏览器渲染,减小Dom数、按需延迟加载、次要信息异步化加载、使用BigRender技术控制渲染节奏优化首屏时间、使用前端模板引擎进行页面渲染。某应用后端数据大小是前端页面大小的1/10,若是只传数据不传页面能够大幅节省页面下载时间,咱们采用前端渲染方案优化后,系统响应时间减小25%、页面大小减少60%、domReady时间减小60%、onLoad时间减小70%。在前端性能优化领域,Google一直在引领潮流,基于Chrome这个入口推进不少优化落地、推出PageSpeed、WebP、SPDY等技术,带给咱们不少新的方向。

相关文章
相关标签/搜索