web应用性能优化经验总结
常见性能优化要求
在我经历的性能优化案例中,常见的问题都是这样开始的: a) 前台访问很慢,请帮忙分析优化 b) 用户对性能很不满意,再不解决就要投诉 c) 数据库负载很重,请帮忙分析一下 d) XXX功能打开需要1分钟,请帮忙分析一下。而等我访问这个功能的时候,可能几秒钟就返回;等你满怀困惑的找到问题提出人员,如果足够幸运的话,可能他告诉你要选择什么查询条件,问题能够重现;当然另一个可能是他也是转述用户的话。 在接到这些性能优化要求的时候,我都希望能够了解下面的信息以判断问题的类型,而通常情况下,我的工作都是在这些信息并不存在的情况下开始的 a)系统性的问题? 比如CPU利用率,SWAP利用率或者IO过高导致的整体性能下降? b)功能性问题? 整体性能良好,个别功能时延很长 c)新出现问题?什么时候开始的,之前系统有哪些变动?(升级或者管理的资源大量增加) d)不规律问题?有时候快,有时候慢,没有特定规律 还有性能快慢的衡量标准是什么?原来多少秒,现在多少秒,目标是多少秒? 只有上述问题得到了准确的回答,优化工作才能开始。 而获取上述答案的方法就是测量,有可靠的监控工具对用户的访问时延,系统的CPU,IO,SWAP进行准确的测量,当系统发生性能瓶颈时,系统当时的状态,数据库当时的状态进行及时的记录,依赖这些数据才能开始优化。 案例1,天津客户曾经有过投诉,系统经常性的出现整体性能下降,几乎无法访问的情况,而且发生的时间没有任何规律。我部署了监控工具,3周后分析数据,发现访问性能下降之前用户都执行了某一个历史告警查询,而在此之后的数据库性能曲线也急剧下降。研发人员对此功能优化后,问题再也没有出现。 案例2,南京客户某主机经常崩溃,根据监控工具在崩溃前记录的进程列表看,是某个程序挂起导致的进程越积越多,资源耗尽而崩溃,对该程序改进后,故障再未发生。 只所以费这么多笔墨,就是希望能够让各位明白,没有定量的测量,性能优化工作完全是空中楼阁,无法进行。而通过工具的部署和监测,今后我们提出的性能问题可能就是这样: a) 系统整体负载正常,但/nms/res/devicelist_down.jsp目前经常出现35046毫秒的访问时延,请协助排查一下 b) 系统SWAP利用率经常会超过50%,这时候系统响应很慢,杀掉GetCGFlux.pl后恢复正常,请分析一下 c) 或者数据库服务器目前CPU利用率居高不下,已经持续了一段时间,请分析一下 如果性能优化工作以这样的方式开始的话,这项工作就会变得轻松有趣得多了。 优化分析过程
1. 性能数据收集 这一步是性能优化的基础,如果问题系统之前没有部署监控工具的话,那么就要部署监控工具,收集一段时间的数据后才能开始分析;当然也有例外,幸运的话,性能问题正在发生并且如此显著,比如某个程序长时间无法挂起,或者某个进程把整台主机的CPU都吃掉,或者某个功能查询很慢,次次如此。当然这种问题也就很少需要到我这,你就可以直接找开发人员解决了。 很多情况,问题可能不是那么明显,也不是那么规律,可能也涉及到系统的多项功能,这个时候,我们就必须要借助于工具来进行数据的收集。 2. 性能数据分析 如果没有数据收集,分析工作可能很神秘,完全依赖于专家的个人经验。以前听过一个故事,一个工厂的打印机总是莫名其妙的在某个时间出现故障,后来请了一个专家,搬了把椅子坐在打印机附近,几个星期后,叫工人把地板的某个角修好,之后这个问题再也没有出现。 但是有了之前收集的数据,观察CPU,IO,应用时延,网络性能等不同指标的曲线,观察问题出现的时间点,存在问题的功能,任何一个IT业者,都应该具备从这些数据中发现问题的能力。 例如某台采集机SYSLOG处理经常出现会滞后的情况。而这台机器的网络丢包是这个样子的,那么问题是不是显而易见?
3. 实施优化工作 这一步主要是针对之前发现的问题,采取措施。可能是系统维护人员调整采集负载,让负荷更均匀;或者调整主机或数据库参数;当然更多的可能是程序需要优化 4. 评估优化效果 譬如上述第二个例子,采取优化措施后,无论是网络连接数还是数据库主机负载,都已经很平稳,而问题也不再出现。
这个工具箱是我常用的性能分析工具,曾协助我解决了很多的性能优化难题 a) web访问时延监控工具AssayFilter 部署在主应用上 部署后可以在resin/logs/AssayFilter.log里面看到访问时间,访问的用户,访问的URL,时延毫秒,来源IP,据此我们就可以将用户的感知定量化,数据化 20150227094607 zengguojin /nms/res/devicelist_down.jsp 309356 219.159.77.116 ms 20150209113913 zengguojin /nms/res/devicelist_down.jsp 383042 219.159.77.116 ms 从这两条数据里我们可以知道这个用户在访问这个功能时候遭遇过多次等待300多秒的情况,他又会有怎样的满意度呢?
针对这个工具可能有人怀疑是否准确,是否统计时延过高是网络延迟导致。这里解释一下他的工作机制, 如下图: AssayFilter作为一个拦截器,统计的是访问请求进入resin之后和应答离开resin之前的时长,访问时延=resin处理时长+主应用到数据库网络时延+oracle的SQL执行时长 主应用到数据库都在一个交换机上,所以主应用到数据库网络时延可以忽略不计。
| perl@unknown (TNS V1-V3) | 2015/3/27 12:37 | fuuk7dbrmsk47 | 2158 | 214293 | select probeid,cfgfiledir,cfgfilename,to_char(lastgottime,'YYYYMMDDHH24MISS'),resid from cfgfilelist |
| JDBC Thin Client@pon-gx-app | 2015/3/26 7:29 | db6b71unjzah1 | 9 | 5 | INSERT INTO RCHECKRESGROUPRES (PLANID,GROUPID,RESID,IPADDRESSA,RESNAME,NODECODE,NODENAME,NODEFULLCODE, |
1. 主机基础故障问题 磁盘空间是否空闲为0? SWAP利用率是否超过40%? CPU利用率是否长时间超过85%? 网络是否持续丢包? 工作磁盘IO的利用率是否持续100%? 上述状况通常意味着系统有较严重问题,需要进一步从程序或者数据库上查找原因。 2. resin的JVM检查 Web应用的前台程序jsp和class都是运行在resin的JVM里,JVM(Java虚拟机)类似于oracle数据库,jsp和class类似于SQL,都可以看作一个系统软件,那么仅仅是看java进程在不在,前台能不能访问是不够的。就像没有sqlplus,PLSQL我们就无法维护数据库,同样的JVM也有相应的维护工具,,都在JAVA_HOME/bin下 a. 查看JVM的内存占用情况 jstat -gcutil
0.00 98.51 44.95 39.41 63.43 9 0.070 2 0.195 0.266 永久内存区利用率63.43%, Elden和old区分别是44.95%和39.41% b. 查看JVM的堆栈调用情况 jstack
substr(s.machine,1,15) smachine,substr(s.program,1,20) sprogram,q.sql_id,substr(q.sql_text,1,200) sql from v$sql q,v$session s,v$process p
where q.hash_value=s.sql_hash_value and q.address=s.sql_address and p.addr=s.paddr 基于两个判断标准我们能很快的找到问题SQL 第一种是某个进程执行的SQL占用的CPU非常高,CPU利用率从Top命令获得,进程ID即PID 第二种是某类进程执行的SQL非常多,单个CPU不高,但合并起来就非常高了。 针对SQL就可以找支撑人员进一步判断是否需要找开发人员优化。 2) 是否存在session被其他session阻塞的情况 查看上一SQL结果的blocking_session字段,如果被阻塞的进程都被某一会话锁定,需要把该session杀掉 alter system kill session 'sid,serail#'; 遇到过几次系统非常慢的情况,经查看都是开发或者维护用plsql把某表锁住,导致相关会话都被阻塞 3) 对该SQL所涉及的表进行表分析,更新其统计信息 性能优化非常精深,很多东西我也在学习,这篇文字,供大家分享。