J2EE性能问题的分析

来源:互联网 发布:笨办法学python 元组 编辑:程序博客网 时间:2024/05/21 07:59

故障征兆

       应用程序出现性能问题的征兆是什么?您所观察到的故障征兆诱导你对所有可能出现问题进行全面检索。拿起笔记本开始向人们收集数据。努力从假定推断中抽身出来,以确凿的证据认定系统的实际行为,查找引起性能问题的根本原因。系统中常见的故障征兆列表如下

       ■ 持续运行缓慢。时常发现应用程序运行缓慢。通过改变环境因子(如负载量、数据库连接数等)也无法有效提升整体响应时间。

       ■ 系统性能随时间的增加逐渐下降。在负载稳定的情况下,系统运行时间越长速度越慢。可能是由于超出某个阈值范围,系统运行频繁出错从而导致系统死锁或崩溃。

       ■ 系统性能随负载的增加逐渐下降。随着用户数目的增多,应用程序的运行越发缓慢。若干个用户退出系统后,应用程序便能够恢复正常运行状态。

       ■ 间发性的系统挂起或异常错误。有时候可能受负载或其它因素影响,当面不能完全显示,又或者是追踪到异常和堆栈的错误页,用户此时会看到系统挂起的情况。系统挂起的次数可能会稍有不同,然而即便是经过预烧(“burn in”)试验也无法完全消除。

       ■ 可预见的死锁。系统挂起或系统出错发生的频率随着时间的推移明显增多,直到系统完全死锁。通常借助自动重启的故障管理模式解决上述问题。

       ■ 系统突然出现混乱。系统正常运行,且在或多或少的一段时间内(譬如,可以是1小时也可以是3天)拥有一致优越的运行性能,却突然毫无征兆地出错甚至死锁。

 

性能问题的诊断为何如此困难

       特定使用模式下应用程序的性能优劣并无现成规则可循。(就严格意义上的实时工程而言,借助速率单调分析等方法的确可以完成这项工作,但已超出本文研究的范畴,在此不做讨论)。网络中是否存在另一个系统正在密集使用共享的后台服务,必将极大地影响系统的实际性能。系统性能或许还取决于JDBC驱动程序与数据库版本是否严格匹配。也可能出现这样的情况:开发人员三年前编写的代码,恰巧在这个时候出现特定类型的异常,而您急需的用以解决问题的回馈信息偏偏包含在那些异常当中。

       典型业务系统的性能呈现整体涌现性(emergent property)特征,是成千上万个变量(交互式)和决策共同作用的结果。就如同人的身体,是一个由众多联锁的组成部分和过程构成的整体。在文中我们采用统摄性模式以简化问题。

 

故障现象

       您所观察到的“疾病”征兆的根本原因是什么?是普通流感还是肺炎初期?是应用程序内部潜在的性能问题还是JVM外部进程出现了问题?下表是应用程序性能下降的常见原因列表,具体如下

 

       “疾病”描述征兆原因或解决方法内存泄漏呈线性增长各单元(如每个事务或每个用户等)的内存泄漏,导致内存使用率随时间或负载的增加呈线性增长。系统性能随时间或负载的增加大幅下降,重启后系统可恢复正常系统性能随时间的增加逐渐下降, 系统性能随负载的增加逐渐下降虽然有许多外在因素存在(如各单元数据的链表存储、尚未回收的缓冲中的回收或增长操作等),但最为常见的原因还是资源泄漏内存泄漏呈指数级增长内存泄漏呈双倍增长,导致系统内存消耗随时间呈指数曲线变化系统性能随时间的增加逐渐下降,系统性能随负载的增加逐渐下降虽然有许多外在因素存在(如各单元数据的链表存储、尚未回收的缓冲中的回收或增长操作等),但最为常见的原因还是资源泄漏导致无限循环的编码缺陷线程在while语句返回值为真的情况下发生阻塞, 将最终演变成为CPU密集型和等待密集型或螺旋等待变量可预见的死锁需要进行侵入式循环切除资源泄漏JDBC语句、CICS事务网关连接等出现资源泄漏,引发Java桥接层和后台系统出现严重性能问题系统性能随时间的增加逐渐下降, 可预见的死锁, 系统突然出现混乱通常是由于遗漏了Finally模块,或者只是没有用close函数关闭代表外部资源的对象外部瓶颈后台或其它外部系统(如用户验证)运行缓慢,大大影响J2EE应用服务器及应用程序的运行速度系统持续缓慢运行, 系统性能随负载的增加逐渐下降向专家(包括可靠的第三方或系统管理员等)咨询特定外部瓶颈问题的有效解决方法外部系统的过度使用J2EE应用程序发送的请求过大过多,滥用后台系统资源系统持续缓慢运行, 系统性能随负载的增加逐渐下降消除冗余的工作请求,分批处理同类工作请求,把大请求细分为若干个小请求,调整工作请求或后台系统(例如为公共查询的关键字建立索引)等频繁调用CPU密集型组件的编码缺陷J2EE领域的通病是:些许编码缺陷或少量编码的交互失败,都会令CPU挂起,从而将数据流量速度降至蜗行系统持续缓慢运行, 系统性能随负载的增加逐渐下降最好的解决方法是将数据存储在本地缓存中,或者为执行算法配备高速缓冲存储器桥接层本身存在的问题桥接层(如JDBC驱动、CORBA到遗留系统的连接等)存在执行缺陷。需要不断对数据和请求作编组和取消编组操作,导致该层的数据流量速度降至蜗行。这种故障现象在早期阶段与外部瓶颈极为相似系统持续缓慢运行, 系统性能随负载的增加逐渐下降检查桥接层与外部系统的版本是否兼容。如果可能的话,对不同桥接供应商进行评估。通过重新规划设计系统架构,则可完全旁路桥接层内部资源瓶颈:资源的过度使用或分配不足内部资源(如线程、放入存储池的对象等)匮乏,却无法判断是正常情况下随负载增加而引起的资源过度使用,还是由于资源泄漏引起系统性能随负载的增加逐渐下降, 间发性的系统挂起或异常错误若因资源分配不足引起,则可依照最大预期负载值上调存储池的最大容量;若因资源过度使用引起,请参看本表“外部系统的过度使用”一栏不断重试失败请求的频繁重试(某些极端情况下将无休止重试)可预见的死锁系统突然出现混乱后台系统可能已经完全宕机。监控系统可用性对这样的状况有所帮助,也可以只是将多次重复尝试的请求从成功的请求中筛选出来线程阻塞点线程退回到无法完成的同步点,造成通信阻塞系统性能随负载的增加逐渐下降, 间发性的系统挂起或异常错误, 可预见的死锁, 系统突然出现混乱或许根本没有必要进行同步(只需对系统重新设计稍加改良),当然也可以定制一些外在的锁定策略(如读取器或写入器的读/写锁)线程的死锁或活锁通常只是“获取顺序”问题系统突然出现混乱解决方法选项包括主锁、即定的获取顺序以及银行家算法网络饱和等待时间长或基本无法将任何请求打包,导致系统异常停运、系统挂起或活锁等情况的出现系统持续缓慢运行, 系统性能随负载的增加逐渐下降, 间发性的系统挂起或异常错误如此棘手的问题正在侵蚀着网络系统,如果不及时升级系统的基础架构,提升网络及路由器的运行速度,将无法扼制日后类似问题的出现