网站性能优化的体验

发表于:2016-1-18 14:03

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:老李(laoli0201)    来源:51Testing软件测试网采编

  这篇文章是关于网站性能优化体验的,性能优化是一个复杂的话题,牵涉的东西非常多,我只是按照我的理解列出了性能优化整个过程中需要考虑的种种因素。点到为止,包含的内容以浅显的介绍为主,如果你有见解能告知我那再好不过了。无论如何,希望阅读它的你有所收获。
  我眼中的网站性能问题都反映了一个网站的“Availability”(中文叫做可用性,但是这个翻译也不足够达意),以往我的认识是,这个网站如果全部或者部分不可用,那是功能问题,但是如果响应慢、负载差,这才是性能问题;可是后来我逐渐意识到,性能问题涵盖的范围更广,我还没法给出一个准确定义,但是许多非业务逻辑错误引起的网站问题都可能可以算做性能问题,比如可扩展性差,比如单点故障问题。
  在网站性能优化的最初阶段,也就是所谓的“第一重境界”,做局部的定位、分析和修正,考虑的仅仅是“优化”,这也是初涉性能优化问题的大多数人的认识。在问题发生以后,发现它和业务逻辑没有太大关系,就开始尝试寻找问题产生的原因并加以解决。
  无论是网站无响应还是响应缓慢,还是响应曲线异常波动,比如,可以围绕CPU的使用问自己这样几个问题:
  · 从CPU使用看系统是否繁忙?
  · 如果系统繁忙,系统在做什么,为什么?(典型问题:HashMap不安全并发导致的死循环)
  · 如果系统空闲,那么瓶颈在哪里?(典型问题:IO无响应)
  · 如果响应波动,是否存在周期,周期是什么?(典型问题:连接迅速占满,每一周期批量超时断开一批)
  · 如果响应波动,性能到波谷时系统在做什么?
  · 是否有背景CPU使用?(即无压力下观察CPU的使用情况。典型问题:正执行的定时任务占用过多系统资源)
  在这些问题中,情况虽然千变万化,简单地说,CPU的使用是核心,CPU使用率高,说明系统资源被充分利用,可能系统在实实在在地做事,反之,需要寻找其他瓶颈。通过结合进程、线程的快照,来初步确定问题的范围。CPU使用率低的情况居多而且容易定位,只需要寻找其他的系统瓶颈;CPU占用率偏高的问题往往比较不容易定位,虽然也有一些办法。关于具体性能问题的定位技术,这里不着过多笔墨,后续有机会详细介绍。
  对于一个刚开始做性能优化的网站系统,下面的事情不妨都做一做,会有立竿见影的效果:
  · 对于使用的成熟的技术,技术社区、官方文档,往往会给出这种技术的白皮书或者优化指导,请参考。比如 Struts2的官方性能调优指南、Java6性能优化白皮书。
  · 平台和虚拟机调优。对于使用平台和虚拟机的项目来说,这是必须要做的,一个JVM的参数可以对系统有显著的影响。比如Linux下连接管理的参数,JVM关于堆大小分布的参数等等。
  · 前端审查。这里的审查指的是通过Page speed、YSlow等工具,以及一些业界通用的法则和经验(比如yahoo的若干条前端性能优化法则)来评估现有页面的问题。
  如果你需要系统的指导,不妨参考这张图:
  从使用的工具上说,性能问题的定位很大程度上是面向操作系统、虚拟机系统的问题定位。从问题定位的时机上说,又可以分为:
  · 截取型:截取系统某个层面的一个快照加以分析。比如一些堆栈切面和分析的工具,jstack、jmap、kill -3、MAT、Heap Analyser等。
  · 监控型:监视系统变化,甚至数据流向。比如JProfiler、JConsole、JStat、BTrace等等。
  · 验尸型:系统已经宕机了,但是留下了一些“罪证”,在事后来分析它们。最有名的就是JVM挂掉之后可能会留下的hs_err_pid.log,或者是生成的crash dump文件。
  了解到这里,再给出这样几个常见问题定位的场景:
  第一类:请求无响应,浏览器始终处于等待状态。
  定位方法:kill -3或者jstack先分析线程堆栈,找到当前block的线程。
  常见于:外部接口调用无返回或者网络IO阻塞无响应;死锁;死循环;……。
  第二类:宕机,进程挂掉。
  定位方法(这一类问题普遍比较难定位):
  (1)寻找hs_err_pidxxx.log这样的JVM日志
  (2)使用JVM参数在JVM crash时写入到dump文件中
  (3)catalina.out中寻找最后的日志
  (4)宕机前环境数据采集
  常见于:JDK bug(数次遇到过JIT引起的这一类问题);调用dll的问题;……
  第三类:请求响应时间长。
  定位方法:kill -3或者jstack先分析线程堆栈,看线程大都停留在什么操作上面,再细化分析。
  常见于: 内存不足,可见到连续的Full GC;网络拥塞;LoadRunner等压力客户端瓶颈;数据库瓶颈,可进一步分析DB快照;……
  第四类:TPS低;TPS逐渐降低;TPS振荡幅度过大。
  定位方法(这一类问题最常见,定位的方法也最复杂):
  首先观察在压力增大时,CPU使用率能否上去,如果不能上去,寻找其他瓶颈:网络/内存/磁盘/……;CPU
  使用率上去了,观察在无压力时,是否有背景CPU使用(例如有后台定时任务线程消耗了大量CPU资源),如果没有,那可以尝试JProfiler等工具结合线程分析、业务分析,寻找热点。
  常见于:其他业务线程干扰;内存泄露;连接句柄用完;缓存命中率低下……
  好,暂时说到这里,下面来看第二重境界。达到这重境界意味着已经能够跳出“事后优化”的局限了,在设计和编码的过程当中,能够正式和全面地考虑性能的因素,比如:
  · 减少使用时间敏感的容器管理,而使用容量或数量敏感的容器管理。比如我往一个缓冲里面存放若干数据,一种设计是每10分钟flush入库一次,还有一种设计是数据到达10M大小的时候flush入库一次,通常情况下,你觉得哪个方案更可靠?
  · 线程的统一管理使用。我的经验是,10次对线程创建或者线程池的使用,往往就有5次是会出问题的。
  · 避免使用同步Ajax。同步Ajax会造成浏览器假死,直至响应返回。
  · 分析对同步、锁的使用。即便在一些有名的开源库中,我们也不止一次发现过不合理的同步设计,N多数据,单一的全局同步块(这是一种性能设计层面上的“中心化”),结果它就成为了瓶颈,改动还不容易下手,很麻烦。
31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号