WebLogic性能调优:速度不是一切
追求原始速度的过程,会使可读性强的代码变得晦涩难懂(通常是无用的——目前的优化编译器相当不错),从而导致以后维护困难;而且在很多情况下,整体方案中的优化性能指标无法吸引人们的兴趣。很多人只注重完成一次请求所需的时间——“这次交易仅用了20微秒就从储蓄帐户中取出500英镑,哇!”
对于事务型系统来说,系统的吞吐量通常远远要比一次请求的绝对速度更吸引人(尽管这么说,执行事务所需的时间还是必须满足某种限制条件)。吞吐量衡量系统在达到响应时间目标的情况下可以处理的工作量。当然了,系统中更多的客户端请求事务是产生更多工作的部分原因。此处的另一个有趣的因素是,响应时间和客户端数量不是独立的变量——抛给系统工作的客户端越多,单个事务就越有可能使用更长的时间。因此,(在给定的部署环境下)系统的最大吞吐量支配着多少个客户端可以以某个预期的速率提交事务,并将多少事务(比如说90%)的响应时间维持在要求的时限内。得出这个结论以后,在尝试预测生产设置以满足所需的服务水平并优化服务器资源的使用时,更改各种系统参数(执行线程数、数据库连接数、机器数等等)会不断地产生有趣的结果。
事实上,对于任何使用应用服务器的人来说,单个事务的个体往返时间对性能没有太大影响已经不是什么新鲜之谈了。很明显,优化的方式是尽可能地缩短客户端和该客户端所作用的后端之间的代码路径——而客户端和后端之间的应用服务器基础架构中的粘合层显然不利于缩短代码路径。但是,它却能提高吞吐量,这主要是通过在客户端中间共享稀有的服务器端资源(数据库连接、线程等等)而实现的。如果简单地通过缩短代码路径来提高性能,最终只会在客户端数目和服务器上所使用的资源之间建立一对一的关系;而一旦所有的服务器资源都被使用了,就会产生性能瓶颈,吞吐量也就无法进一步得到提升,除非可以整合更多的资源并共享出来。应用服务器的真正作用是,通过在客户端之间共享来节约服务器端所使用的资源数(代价是会产生较长的代码路径,这暗示着会或多或少地延长事务的往返时间),从而提高系统的最大可能吞吐量。从这方面来说,“我不使用事务,它们会降低速度”的说法是有道理的。
到目前为止,我们已经看到,系统要在有限的服务器资源下运行尽可能多的请求。但是没有说所有这些请求必须得到正确的结果——也就是说,任何独自执行的请求的结果应当与它与其他许多请求一起执行时所得到的结果一致(或者说,请求应当具有隔离性,当然了,隔离性(isolation)就是ACID中的“I”,而提供ACID属性的是事务)。因此,使用XA事务的代价是牺牲一点点绝对性能,而益处是得到正确的事务结果。如果您存款的银行使用XA,那么您就可以高枕无忧了,因为您知道,即使在某些模糊负载条件下从银行帐户中提款也不会出错!
这些讨论全都发生在数据层——XA完全是关于数据库事务的。每一个事务会将数据锁定在数据库中,直到事务完成;随后等待方才能看得到结果。当多个请求试图访问相同的数据时,事务就会引发瓶颈问题——除了第一个锁定争用数据的请求之外,其他请求都被阻塞或抛出,从而严重地影响了吞吐量,因为正在做的工作不会导致系统中有一个良好的事务流。
然而,数据库中的数据不是事务系统中唯一共享的资源。我已经讨论了应用服务器作为资源共享机制的作用——任一个资源都可能被争用;因此,如果多个请求同时访问,则应用服务器本身需要锁定内存中的数据结构以避免产生问题,而且这里也会产生争用。当然了,除应用服务器之外的各层也进行资源共享——在一个典型服务器中,为WebLogic配置的60个执行线程很可能至多在几个CPU中执行——当发生CPU争用时,那些不走运的线程就必须在队列中等待,直到某个CPU空闲;内存或者硬盘也是如此。
总之,到目前为止我所提到的都是大问题——性能测试的开发、完成所有调优后测试的运行、满足预期要求的服务器资源分配,这些都随着不断变化的应用程序版本和服务器环境版本而反复进行,产生的特定系统必须承受得起不可预知的实际负载。这些不只是难题,也是每一个应用程序生命周期成本的主要部分。
聪明的读者会注意到我的电子邮件地址已经变更;这是因为我已经加入了Azul Systems,该公司有应对上述问题的独特解决方案。Java是多线程的,因此可以提供包含多个CPU且每个CPU都具有多个内核的系统;这些Java线程实际上就产生了并行化;其次,它提供对同步Java对象的乐观锁定的支持,以减少Java软件层中的争用;再次,它提供可以在多个应用程序之间共享的内存池。总而言之,Azul Appliance提供了一种Java执行引擎,它通过为单个应用程序提供大量的CPU和内存资源,从而试图缓解传统虚拟机环境中由于CPU或内存不足而产生的瓶颈,从而降低了系统使用的资源量。
该策略还有另外一个优点,即它在一定程度上避免了基于每个应用程序进行调优的需要,这是因为设备提供的资源非常多,以至于可以轻松地在多个应用程序之间共享;而以前,每一个应用程序都需要在自己的服务器上为需求峰值预留一定的空间。这种共享是可以实现的,因为总的来说,需求峰值是平滑的(因为很多不相关的应用程序同时达到需求峰值的情况不大可能发生);因此,需求可以通过池化的资源得到满足,从而使您既不用担心应用程序级的大小(以及相关成本),也不用担心每个应用程序基础上的硬件过量供应。这预示着一个以低成本采购和管理的设备来运行高性能Java应用程序的新时代来临了。
您可能感兴趣的文章
Logiscope测试机理[2]
Logiscope测试机理[1]
WebLogic Server中CMP实体bean的性能调优[10]
WebLogic Server中CMP实体bean的性能调优[9]