企业java应用的性能调优是一项艰巨的、有时甚至是徒劳的任务,这是由现代应用的复杂性和缺少正规的调优方法导致的。现代企业应用与十年前的应用相比差距很大,如今这些应用支持多输入、多输出、复杂的框架和业务处理引擎。而十年之前,基于web的企业应用只是通过网络浏览器获得输入信息,然后与数据库或者遗留系统交互进行后台处理,最后把输出结果返回给浏览器(HTML)。现在,输入信息可以来自HTML浏览器、富客户端、移动设备或者网络服务,它可以跨越运行在不同架构下的servlets或者门户容器,这反过来又可能调用企业bean,外部web服务或者把处理委托给业务规则引擎。每一个这样的组件都可能与内容管理系统、缓存层、众多数据库和遗留系统交互。输出的信息通常以独立于展现层的形式保存,随后转化为HTML、XML、WML或者其他任意客户端需要的格式。现代应用比过去包含更多移动部分和“黑盒子”,这对性能调优提出了巨大的挑战。
除了复杂性提高,性能调优技术其艺术性要大于科学性,还因为大多数性能调优指南都侧重于性能指标,有时晦涩难懂,也可能影响用户体验。本文尝试把性能调优活动变成一种“科学”范畴内的行为,提供了一种可重用的关注用户体验的方法,利用“等待点”(也就是应用中引起某请求等待的部分)分析应用架构。总之,基于等待的调优方法允许性能工程师们通过优化用户体验快速实现可度量的性能提高。
性能调优过程
在详细介绍基于等待调优和等待点分析方法之前,本节首先对有效的性能调优过程做一个概述。性能调优可以简单的概括为四步:
1、负载测试
2、容器调优
3、应用调优
4、迭代
像大多数计算机科学一样,性能调优是一个迭代的过程。首先,创建一个合适的负载测试,其中包含了均衡的、具有代表性的服务请求,这都是容器调优实践可以满足的。随着容器被不断调优和测试压力的增大,应用程序的瓶颈逐渐显现出来。随着应用的瓶颈被定位和解决,应用行为会发生变化,这就要求容器再次调优。在容器和应用之间的迭代过程会一直进行到性能到达可以接受的条件(或者直到项目已经到期必须发布时)。
负载测试方法
启动一个性能调优实践的先决条件是创建一整套合适的负载测试集合。每一个负载测试必须满足以下两点:
● 代表性,必须体现最终用户的业务场景(或期望的场景)
● 均衡性,必须符合最终用户不同行为的比例分配
也就是说,负载必须能够按照最终用户的实际操作比例来模拟用户动作。为了说明均衡最终用户动作的重要性,请看下面这个例子:在保险索赔部门,员工执行以下操作:
1、用户上午八点登陆系统。
2、上午每人平均处理五个索赔请求。
3、大约80%的用户忘记在吃饭之前注销账号,导致session过期。
4、午饭后,用户重新登录系统。
5、下午每人平均处理五个索赔申请。
6、下班之前生成两个报告。
7、80%的用户回家前注销账号。
这个例子是一个真实应用的简化版,但是它足够在这些服务请求建立一个平衡。这个场景展现的均衡是:两次登陆,十次索赔处理,两次报告和一次注销。
如果负载生成器把压力均匀分布在不同的服务请求上又会怎么样呢?在本例中,用户登陆和注销功能会接收与处理与理赔请求相同的负载。如果是1000个并发用户,登陆功能会很快崩溃,导致企业投资建立一个能够处理这种负载的登陆组件,而实际上这种负载根本不会发生。更糟糕的是,本例中由于最大的瓶颈看似存在于登陆功能上,所以调优的努力会侧重该功能,而忽视索赔处理功能。总之,一个非均衡的负载可能导致调优过程错误的关注于支持那些绝不会发生的负载的组件,而不是那些真正需要调优的部分!
判断一个负载对于应用是均衡的和代表性的标准,对于测试一个已存在的应用(或者一个新版本)还是一个全新的应用是不同的。