20 May 2015

本文主要根据IBM红皮书的介绍和自己的理解,做一些性能调优的总结。

应用程序的结构,基础设施,和这个系统需要承受的负载量是影响到性能参数配置的三个因素。不可能有任何一个固定的值是适用于所有系统的。我们需要系统容纳能力的规划,压力测试,收集信息,最后分析结果来确定对我们自己的系统来说最佳的配置。

要进行性能调优,我们需要有一套跟自己的生产环境环境相同的性能测试环境。为了让测试结果真的有意义,我们要确保测试环境中的软件和硬件跟生产环境上的完全相同。

为了让我们的测试成功,我们需要生成符合以下特征的负载:

  • 可计量的:使用可以量化的计量单位,比如吞吐量和响应时间。
  • 可重现的:确保多次同样的测试可以重现同样的结果。每次只更改一个参数,然后其他条件不变,这样就可以知道那个参数对系统真实的影响。
  • 静态的:要确定是否一样的测试不论执行多久,都能得到一样的效果。
  • 典型性:确保生成的负载可以真实地代表正常操作一个系统的压力。

要想确定性能的目标,首先我们必须清楚地理解我们系统的架构和需求。查看架构文档,用例图,以及功能性和非功能性的各种需求,从而确定对自己的系统来说,性能好的标准是什么。

确定一个好坏性能的标准。没有一个标准或目标,我们无法确定性能调整是否成功。要避免使用那些非指向性的标准,比如尽可能地调试为性能“最好”的状态。时刻记住如果没有一个标准线,性能测试可能无穷无尽,因为每次测试都有可能发现一个新的瓶颈,不同的瓶颈又有不同的解决方案,这样的话到最后我们无法确定我们的性能调试到底是成功了还是失败了。

不要尝试在有真实负载的生产环境上做性能调试,这么做的话,服务器有很大几率会做资源回收以使新的参数生肖,这些回收进程可能引发宕机时间。

使用队列类推法去调试WebSphere资源池

WAS的功能非常类似于一个由互通的代表各种各样不同资源的队列组成的队列网络。这些资源池包括网络,Web服务器,Web容器,EJB容器,ORB(Object Request Broker),数据源,还可能会有连接到自定义的后端系统的连接管理器。每种资源都代表着等待使用那些资源的一个请求的队列,这些队列都是容易受负载影响的资源,也就是说,平均响应速度取决于客户机请求的数量。这样的话,性能调优实际上就是对这些队列的调优。

举例来说,某个应用程序包含servlet和需要访问数据库的EJB beans。每个部分都被放置在了适当的WebSphere组件上(例如servlet在Web容器里),在确定的时间段内,每个组件可以处理确定的数量的请求。

客户机的请求会通过Web服务器,穿过WebSphere的几个组件之后WebSphere组件会给客户机提供响应。下面图解了这个应用程序通过WebSphere组件处理客户请求的路径,我们把这个路径类比成一些连接在一起的互通的管道。

图中管道的宽度代表了在给定的时间里可以处理的请求数量。管道的长度代表了从收到请求到提供响应需要的处理事件。

上图展示了在一个确定的时间内,一台Web服务器可以处理50个请求,一个Web容器可以处理18个请求,这就意味着在最大负载的情况下,请求会在Web服务器上排队以等待空闲的Web容器。EJB容器可以处理9个请求,因此一半的Web容器的请求需要排队等待可用的ORB线程池。而数据库看起来有足够的处理能力,因此EJB容器里的请求不需要等待数据库连接。

假设我们的WAS系统中有足够的CPU和内存资源,这时,我们可以增加ORB资源池的大小来最大化地利用数据库连接。由于Web服务器在一个确定的时间内可以处理50个请求,我们也可以增加Web容器的线程池来获得更多的Web容器线程从而跟ORB的增长相匹配。

然而,如何确定线程和数据库连接的最大值呢?如果我们的系统采用队列处理的方式,要想获得最佳的性能,我们到底应该从数据层开始调整呢还是应该从客户端开始调整?下面的章节提供了答案。

Upstream queuing (上游队列)

资源池调优的黄金法则是:尽量减少在WAS队列中等待的请求数,根据Web服务器前等待的资源来调节资源池。这样的配置使得只有准备好被处理的那些请求能够进入相应的队列。想要达到这种配置,需要让上游的队列(靠近客户端)配置得稍微大一些,二下游的队列(远离客户端的)要逐渐的变小。这样的方式叫做“Upstream queuing”。

下图13-2展示了这种配置。当200个客户请求到达Web服务器时,125个请求依然在网络中等待,因为Web服务器设置为只能同时处理75个客户请求。当这75个请求从Web服务器传送到Web容器的时候,25个请求被留在Web服务器中等待,50个请求进入到Web容器中被处理。当25个用户请求到达最终的目的地——数据库服务器时,这个处理的过程才会出现进展。由于在每个节点的上游都有一些请求等待进入被处理,所以这个系统中的每个组件都没有处于闲置状态等待请求进入。大量的请求在WAS之外的网络中进行等待,这样的配置增强了系统的稳定性,因为没有任何一个组件是过载的。

由于我们的系统不可能有无限的物理资源,所以不要使用等体积的队列。如果你有无限的资源,你可以调整你的系统使得每个Web服务器的请求都能得到一个Web容器的线程去处理,每个线程都能得到可用的数据库连接。然而在现实世界中,这样的配置是不可能出现的。

另一个精确调节资源池的重要法则是必须对我们的基础设施、应用程序架构和需求有一个清晰的认识。不同的系统会有不一样的访问和使用的方式。

比如说,在多数情况下,只有少部分的请求需要不断向下通过各个队列进行处理。然而,在一个静态页面居多的网站,大量的请求都被填充到Web服务器,不必进入Web容器进行处理。在这种情况下,Web服务器队列可以明显地大于Web容器队列。在上个例子中,Web服务器队列设置为75,而不是接近应用程序的最大并发数。当不同的组件处理请求的时间不同时,我们也需要做一下累死的调整。当静态内容的比重减少时,Web服务器队列跟和应用服务器队列之间的巨大的空隙将有可能造成站点整体性能的下降。所以说,在进行任何性能调优之前,一定要理解基础设施、应用程序架构和需求。

另一个例子,在一个应用程序中,90%的时间都会用来处理复杂的servlet,10%的时间会用来进行快速的JDBC查询,这个10%是一个平均值,servlet可能会在任何时候访问数据连接。这时,数据库连接池就可以明显小雨Web容器的队列。反过来说,如果处理servlet的大部分时间都花费在复杂的数据库查询上了,可以考虑同时增加Web容器线程池和数据连接池的数量。永远记得监控WAS服务器和数据库服务器的CPU和内存使用率,确保服务器没有过载。


下面的章节我们介绍如何调整每个资源池,由最下游的资源池开始,向上介绍。

数据源调试

调整数据源队列时,要考虑下面的设定:

  • 连接池的大小
  • Prepared Statement Cache size

连接池大小

访问任何数据库的时候,数据库连接的初始化都是一个非常昂贵的操作。WAS提供了连接池和连接重用的功能。连接池使应用程序和使用数据库的企业Bean可以进行直接的JDBC调用。

IBM Tivoli Performance Viewr可以帮助我们确定连接池的最大值。模拟正常情况下的客户访问量,使用固定的迭代测试次数,使用标准的配置。观察JDBC Connection Pool模块下的Pool Size,Percent Used,和Concurrent Waiters counters这些项目。最合适的数值应该是比监控到的数值稍大一点(The optimal value for the pool size is the value that reduces the values for these monitored counters.个人理解,意思就是说最合适的值就是一个可以减掉监控到的那些数值的值,也就是说要稍大一点)如果Percent Used使用的百分比的数值始终很低,请考虑减少连接池中的连接数。