UML软件工程组织

 

 

基于 WebSphere Application Server 的应用程序的性能测试规划

2008-06-26 作者:Alexandre Polozoff 来源:IBM

 
本文内容包括:
在本文中,Alexandre Polozoff 提供对基于 WebSphere Application Server 的应用程序进行性能测试的规划,其中有关于规划、建立性能环境、进行实际的测试和测量应用程序的特征的信息。性能测试是确定应用程序在各种负载情景中的(JVM、连接池等)最佳设置的唯一方式。每个应用程序是不同的且在不同的条件下的行为也不同,这意味着所有应用程序在生产环境中被实现前必须经历性能测试活动。

引言

protocol(规划)一词被定义为“科学的或医学的实验、处理或过程的详细规划”。本文提供对基于 WebSphere® Application Server 的应用程序进行性能测试的规划,其中有关于规划、建立性能环境、进行实际的测试和测量应用程序的特征的信息。

性能测试是确定应用程序在各种负载情景中的(JVM、连接池等)最佳设置的唯一方式。每个应用程序是不同的且在不同的条件下的行为也不同,这意味着所有应用程序在生产环境中被实现前必须经历性能测试活动。

性能测试环境

在理想的情况下,性能测试环境应在每个细节(从服务器防火墙和后端资源的数量到网络电缆的规格)上完全模仿生产环境。然而,由于大容量生产环境的大小和规模,这是不实际的。包括最少两台或三台在物理上分离的 WebSphere Application Server 机器的更小的环境是更典型的性能测试的基本配置。


图 1. 基本的性能环境
基本的性能环境
 

如图 1 所示,分布式空间中的基本的性能环境有两台连接到远程数据库并由一台远程 HTTP 服务器驱动的在物理上分离的 WebSphere Application Server。

如果 HTTP 服务器在应用程序的生产环境中是远程的,那么最好使性能环境中的 HTTP 服务器也是远程的。每台 WebSphere Application Server 在自己的节点上独立运行。运行与测试无关的其他应用程序将引入针对本地 CPU、内存和磁盘资源的竞争。这不仅会影响测试的结果,而且这些应用程序与环境的资源的交互是难以估量的。

这两台 WebSphere Application Server 至少应该有相同的机器和 OS 级别的配置。常见的错误包括一台或另一台应用程序服务器使用不同的 OS 补丁或修订包级别或不同的内存配置,这将导致不一致的结果和/或行为。作为题外话,请您一定要确保每台服务器的 TCP/IP 堆栈设置完全相同,尤其是 NIC 卡的双工设置。

在理想的情况下,虽然应用程序数据不必驻留在与管理资源库相同的数据库服务器上,但是管理资源库的所有应用程序数据和数据库将驻留在一台远程的机器上。如果启用了 HTTP 会话持久性,请确保会话表与其他数据库分离且被标记为 VOLATILE。

这并不是说把完全不同的配置用于性能环境是完全不可接受的。在当今的商业环境中,HTTP 服务器常常驻留在每个本地的 WebSphere Application Server 节点上。然而,其中一台 WebSphere Application Server 还作为管理资源库的数据库从而肩负双重责任是不太合乎需要的。这些配置特征和其他配置特征违反了“应用程序不应该参与本地资源的竞争”的约束。性能环境中的这些不平衡可能使最终结果不准确,在许多时候确实如此。然而,虽然折衷的性能测试环境肯定不是更好的选择,但是拥有几乎任何类型的性能测试环境都要比没有环境好。

专用的服务器环境

显然,测试环境应尽可能地与生产环境相似,因为任何差异(任何方面的差异)将引入不确定性。如果您缩小测试环境,那么您必须扩大结果以取得生产环境中的近似数字。类似地,如果 HTTP 服务器在生产中是独立的,但在测试中被包括在应用程序服务器节点上,那么取得的性能结果也不能准确地反映生产中的结果。配置测试环境是作出选择和让步以获取可能取得的最精确的数据的过程。

理想的性能测试环境由专用的服务器机器与连接它们的专用网络组成。如果基于 WebSphere Application Server 的应用程序的服务器也作为其他无关的应用程序或配置的服务器在运行,那么进行性能测试是困难的。您应该将对本地 CPU、内存和磁盘资源的竞争减少到最小,这一点至关重要。

也许最大的困难是把后端资源专用于性能测试。由于在有些安装的操作策略和复制成本,专用的服务器环境并不总是可能的。这一点可以解释为什么人们常常在“夜晚”(此时的后端资源处在轻(或更轻的)负载条件下)运行性能测试。然而,因特网的世界正在不断地使后端资源的利用率达到极限,与此同时跨国公司正向 24/7 运营的方向发展。

缺乏专用的服务器环境可能使性能测试陷于困境。非专用服务器环境中的一些有问题的情景包括:

  • 共享的网络资源:该组织的内部网共享性能环境。这可能造成时有时无的性能结果,这与测试时网络的利用率直接有关。例如,如果有人开始大量利用网络的网络备份,那么这将增加响应时间甚至完全拒绝性能环境中的组件的网络连接。在这种情况下网络嗅探器可被用来帮助了解网络带宽的利用率并确定什么时候的负面响应时间不是由于应用程序造成的。如果您在这种环境中进行性能测试,那么您将遇到很多挫折,这种环境的效率也很低。
  • 共享的后端资源:多个应用程序试图访问相同或相关的数据。这也可能导致比正常情况更慢的响应时间,而且如果在测试中没有直接监视后端资源的工具的帮助来了解利用图,这是难以识别的情况。此外,其他应用程序可能在更改后端资源上的数据,这将增加重复测试的困难,甚至不可能进行。

运行多个被测试的应用程序的 WebSphere Application Server 意味着应用程序和 HTTP 服务器都受到多个测试的额外压力。这是一个完全合理的可运行的情景,因为它进行了多个应用程序的性能系统集成测试。

WebSphere Application Server 环境的基本配置

WebSphere Application Server 环境的一些基本配置常常被误解或被错误地配置。

分层的“门”

一种配置是限制从因特网到 WebSphere Application Server 并最终到后端资源的请求。限制请求的原因是针对应用程序的最佳性能特征来配置它。负载曲线中有一点表示响应时间的增加的直接原因是应用程序处理的请求的数量。当您使用这里描述的规划来确定了这一点后,您就可以“限制”应用程序处理的请求的数量。结果,在应用程序能够处理下一个请求前,在 HTTP 服务器中应使进入的请求排队。您可以通过配置基础结构中三个不同的点来实现限制,这些点可控制流向下一层的请求的流动和容量。

图 2. 限制请求
限制请求
 

图 2 显示了基础结构中的主要组件,从左边开始,请求从因特网进入 HTTP 服务器。然后,请求被发送到 WebSphere Application Server,在这里,应用程序连接到后端资源(例如数据库)。在图中的每一个箭头(共三个)中有一个配置点,这个点可限制进入应用程序并接着进入后端资源的入站请求。限制进入环境的请求可以对最大工作负载调优并提供良好的用户体验。

限制规划

这里描述的限制规划是基于推荐的 WebSphere Application Server 最佳实践、摘自红皮书且被编排过的信息和在大容量客户位置所获得的经验。

根据基础结构中的三个配置点,这个规划有三个步骤:

1. HTTP 服务器并发请求的最大个数

WebSphere Application Server 支持的 Web 服务器都提供定义可接受的并发请求(而不是并发用户)的最大个数的功能。在这里用户与请求的区别被指出,因为包括几个图像的一个 HTML 页面将导致来自一个用户的多个请求。

在 Apache 的世界中,最大的并发请求“门”完全由 MaxClients 设置来控制。(在 iPlanet 上相应的设置是 ThrottleRequests。)对本地的静态内容的请求由 Web 服务器来处理,对应用程序的请求被转发给 WebSphere 插件,WebSphere 插件再把请求向外发送给应用程序。

Web 服务器既处理对本地的静态内容的请求,也处理对应用程序的请求。为了确定 MaxClients 的值,您需要分析发送给浏览器的内容和应用程序服务器中 servlet 引擎线程的最大个数。对于任何使用一台 Web 服务器和一台应用程序服务器的应用程序,用于设置初始值的一般原则是:

maxClient = imageContentPerPage*maxServletEngineThreads

其中 imageContentPerPage 表示 HTML 响应中图像的平均(或最大)的个数,maxServletEngineThreads 表示为应用程序服务器定义的 servlet 引擎线程的最大个数。

这个公式的外推法是基于 WebSphere Application Server 的环境。例如,请考虑有三台 Web 服务器为两台应用程序服务器(它们可以是相同的 ServerGroup 中的克隆)提供输入的情景。那么,公式将变成:

maxClient = imageContentPerPage*maxServletEngineThreads*numberApplicationClones/numWebServers

如果 maxClient 的值太小,那么负载测试客户机将遇到连接错误,这是因为 Web 服务器上的可用的侦听器太少。在这种情况下应使 maxClient 的值变大。

2. servlet 引擎线程的最大个数

您可以通过分析性能测试结果来确定 servlet 引擎线程的最大个数。不存在用于设置这个最大个数的有效的“通用”值,在通常情况下,缺省值 25 对于大容量的应用程序来说太小了。

在设置 servlet 引擎线程个数的最大值时请记住最大 JVM 堆大小设置的数量。每个 servlet 引擎线程被分配给它自己的堆栈,该堆栈将消耗 JVM 中的内存。由于每个 servlet 线程在负载条件下处理请求,您还需考虑在该活动期间创建的对象的个数。请确保 JVM 最大堆大小的设置足够的大以支持增大的 servlet 引擎线程个数并避免内存不足的条件。另外,别忘了您很可能需要启用生成的垃圾收集(请参阅 WebSphere Application Server InfoCenter Performance Tuning Guide中的定义)。

您实际使用的最大值应完全由负载和强度测试期间的应用程序监视结果来确定。请使用应用程序监视器来确定是否所有的 servlet 引擎线程被建立,然后相应地调整最大值并再次运行测试。请记住如果您更改了 servlet 引擎线程的最大个数,那么您还应对 Web 服务器上的 MaxClients 参数作相应的更改。

3. 最大的连接池大小

链中的最后一个“门”是应用程序访问的数据源的连接池的大小。有关连接池的文档(请参阅 参考资料)指出应用程序在执行它们的事务时应该短暂地维持数据库连接。这将使几个数据库连接的高效管理和共享成为可能。广泛接受的数据源连接的最大值是 40,即使在大容量的安装中也是 40,典型的应用程序在 10 至 20 之间。

在这里,您实际使用的最大值完全由负载和强度测试期间的应用程序监视结果来确定。应用程序监视应确定池中被利用的数据源连接的个数。如果最大值的设置是 20 且所有 20 个数据源连接在负载下被完全利用,那么请把最大值的设置增加到 30。请再次运行测试、再次分析扩大的连接池的利用情况并再次确定连接池是否被完全利用。请根据需要再次调整最大值。

为了发现所需的连接的真正的最大个数,作实验是必要的。当打开的连接存在时,形式为影响应用程序性能的内存使用和网络利用的关联开销也存在。虽然确定所需的连接的个数不是准确的科学,但是通过反复实验和应用程序监视,您可以找到可能找到的最佳值。

使期望的测试结果相关

测试结果应该显示负载测试客户机端所看到的数字与应用程序服务器上的数字之间有某些相关性。例如,如果一台应用程序服务器的三个克隆被配置成每台服务器 25 个 servlet 引擎线程并且注意到 servlet 的响应时间小于一秒,那么您应期望看到至少每秒 75 或更多个请求通过应用程序服务器。您还应期望在客户机端看不到 8 秒的响应时间。结果必须同时考虑用于静态数据的 HTTP 连接的数量。请确保测试结果与您在应用程序服务器的配置中看到的东西相匹配。如果结果不匹配,请确保负载测试客户机没有在运行时发出太多的热量(100% CPU)、出现内存不够或遇到某些网络瓶颈。

负载测试客户机

性能测试环境的客户机端对性能测试结果有重大影响。传统的负载测试工具作为代理程序在几台客户机机器上运行。您需要不止一台客户机机器来生成有代表性的容量负载,这是因为 CPU 和内存限制了同时收集准确结果的客户机所能真实代表的用户的数量。

图 3. 负载测试客户机使容量流向服务器环境
客户机使容量流向服务器

在图 3 中,我们的三台负载测试客户机正把负载应用到性能测试环境中的服务器。请注意负载测试客户机没有驻留在应用程序服务器上。客户机应该总是位于与应用程序服务器不同的机器上。

专用的客户机

负载测试客户机机器应被完全专用于负载测试任务。竞争本地 CPU、内存和磁盘资源的其他应用程序不能共享这些机器。这种对本地资源的竞争确实会影响被测量的响应的可靠性。客户机机器应保持在相同的路由器和网络配置上并尽可能地(在网络连接的意义上)接近专用的服务器环境。

还有,负载测试客户机必须能够生成装入涉及的应用程序所需的正确类型的请求。例如,基于对 EJB 的 RMI 访问的应用程序不同于测试对 JSP 或 servlet 框架的基于 HTTP 的请求。

测试的基线和一致性

专用的负载测试机器在不同的性能测试运行之间提供了一致性。在运行于 WebSphere Application Server 的应用程序的性能测试规划的第一步中,有一步是记录一组结果的基线。仅当整个测试情景可被一致地再次产生时(也就是说,您总是可以再次运行基线并获取相同的结果。)基线才是有关的。偶然交换负载测试机器或它们的配置将增加完成“基线”任务的困难(甚至无法完成该任务),此外,这至少会使性能数据的分析含糊不清。

超时

请把客户机页面超时设置为 2 分钟或更短。这将在应用程序没有在合理的时间里作出响应时使客户机端出现错误。很少有用户能够忍受太长的响应时间。

收集和测量结果

整个收集性能数据的练习的一部分涉及获取代表 Java 虚拟机(Java Virtual Machine,JVM)或应用程序服务器的特征的尺度。查看应用程序服务器本身的不同资源以及它们与应用程序的其余部分有关的表现情况的能力是很宝贵的。WebSphere Resource Analyzer 就是一个这样的工具,它提供基于每台服务器的时间开销和资源分配值。其他成熟的工具(例如 Wily's Introscope™ 和 IBM Tivoli® Monitoring V5.1 WebSphere PAC)提供带有补充功能的更多深度数据收集,例如把群集中的多台服务器中的数据编译成一个视图和把收集来的尺度作为历史归档保存到数据库。这些工具还通常在生产监视环境中观察许多相同的关键的应用程序性能点从而肩负双重责任。事实上,性能测试活动可指出在生产中应被监视的应用程序性能点。

图 4. 应用程序监视

在图 4 中,应用程序监视可获取指出应用程序瓶颈和/或后端资源的问题的尺度。

无论您选择什么工具,应用程序监视都是性能测试和问题确定中的一个重要因素。监视提供的能力可测量针对后端资源的应用程序 servlet、JSP 和 EJB 的响应时间,也可测量针对那些由负载测试客户机测量的东西的响应时间。这些尺度有助于识别应用程序的作用域内或作用域外需要关注的问题所在。

历史归档

随着测试的进行,取得的测量结果应该与以前的运行结果相比较以确定性能是提高了还是下降了。应用程序监视工具通常可以用一种格式或另一种格式来保存被收集的数据。更高端的工具甚至可以把结果直接集成到数据库或其他数据存储库。如果您使用的工具不提供用可用的格式来保存数据的方法,那么您可以把相关的数据保存在简单的电子表格中。

程序的时间开销

应用程序开发小组倾向于通过某种记录机制把性能时间开销测量构建到他们的应用程序中。在应用程序中记录性能测量结果的作法应被尽力劝阻,因为这将在应用程序中加入更多代码,这些代码不仅消耗处理周期,还必须被维护和测试。最终,固定在应用程序上并可由一个命令来控制的外部应用程序监视工具的效率更高。

监视 JVM

为了更好地理解 JVM 是如何运行的,您需要在性能测试活动中监视 JVM 的几个重要的地方。一些需要观察的基本参数包括:

  • 活动的 servlet 引擎线程的个数:这使您能够理解 JVM 中的应用程序在任一时刻可以提供的最大工作量。它也有助于确定用于生产环境的所需的最大设置。
  • 活动的 ORB 线程的个数:用于有 EJB 的应用程序。
  • 可用的和用去的内存:有助于理解应用程序是如何利用内存的和垃圾收集周期的执行频率。
  • servlet 响应时间:有助于比较应用程序服务器上观察到的响应时间与负载测试客户机上测得的响应时间之间的异同。通过防火墙和其他网络组件的瓶颈可能带来被记录 servlet 响应时间所证实的延迟。

监视应用程序

应用程序监视是特定于每个应用程序的。您应该考虑监视访问后端资源的重要方法。为了理解序列化/反序列化对象的方法对性能的影响,您必须观察这些方法。

调用的频率和方法执行的持续时间是两个应该被获取的性能数字。频率需被监视以确定在不同的性能运行期间方法被调用的次数。方法执行的时间开销使您深入了解在某些任务上花费的响应时间的占全部响应时间的百分比,也有助于指出应用程序的瓶颈。开发者可以把这些信息用于进一步的代码重构以提高应用程序的性能。

监视后端资源

性能测试期间的后端资源的监视是性能测试活动的至关重要的部分。任何应用程序的性能与环境中最慢的链路一样快。如果后端资源没有提供足够级别的性能,那么访问后端资源的应用程序也不在最佳的级别运行。后端资源的性能下降的原因可能有很多。您需要让每个特定资源的管理员使用正确的工具集和知识以帮助解决这种有关后端的任何问题。

监视网络资源

网络连接的应用程序环境的常见链路是网络本身。参与测试活动的网络资源也必须被监视,它们的数据必须被分析以确保最大的吞吐量和效率。这包括整个网络(包括参与测试的任何防火墙、路由器、CSS 交换机、负载平衡器、反向代理等)。您必须首先解决由于错误配置防火墙、反向代理或其他网络设备所造成的任何性能问题,否则,被收集的数据总是不准确和/或不一致。

需检查的常见网络配置包括:

  • 被设置为半双工而不是全双工的吞吐量。
  • 在往返于相同的一组设备时使用不同跳点的路由。
  • 安装的用于代理而不是通行的防火墙。

应被监视的网络资源:

  • CPU(如果适用的话)。
  • 处于“建立”状态的端口。
  • 连接的吞吐量时间开销。
  • 带宽。

设置性能期望

在性能测试开始前就从几个不同的角度设置期望对于确保测试结果是有价值的且测试活动本身是成功的有很重要的意义。这些期望包括测试小组需要哪些不同的输入和哪些输出将定义合理的应用程序性能。如果您没有提前设置,那么您很难定义被测试的应用程序的性能是否是足够的好。

同样,您必须设置性能测试活动的预期的持续时间。由于测试和被修改的参数的数量较多,性能测试需花去很长时间才能完成。提前安排适量的测试时间将使每个人受益。

应用程序的期望

为了确定应用程序的性能是否是足够的好,您必须定义性能期望。列出以下期望应该是任何测试计划的第一部分:

  1. 可接受的 servlet 响应时间。
  2. 可接受的负载客户机响应时间。由于网络开销、通过 Web 服务器和防火墙的额外跳点等,它不同于 servlet 响应时间。
  3. 可接受的每秒请求的吞吐量。
  4. 可接受的后端资源响应时间。
  5. 可接受的每秒后端请求的吞吐量。
  6. 可接受的网络开销(包括 Web 服务器、防火墙、反向代理、负载平衡器、CSS 等)。

同样,如果测试结果没有满足可接受的结果标准,那么您必须制定处理任何缺点的计划。缓解应用程序中的性能瓶颈的基本策略有两条:

  1. 扔掉更多有问题的硬件,这可能很贵。
  2. 排除应用程序瓶颈,这可能很费时。

虽然预算限制常常是决定中的一个因素,但是根据具体问题,两种策略可能都是正确的和可行的。任一个解决方案都不便宜,但是,一般来说,排除应用程序瓶颈是更好的策略,故您应尽可能采用它。解决应用程序中的性能问题还将导致某种类型的事后分析过程(即记录并传播从这些任务中学到的知识)。

性能测试活动的总共持续时间

不幸的是人们常常在开发周期的结束前(把应用程序转移到生产环境前)安排几周的性能测试。这种思想的问题是直到给应用程序施加负载时许多应用程序问题才会暴露出来,而且只有在性能测试阶段中应用程序才被施加生产环境的预期的负载量。

即使应用程序的问题很少,开发周期的性能测试阶段可能需要几个月才能完成,这取决于应用程序、环境和许多可变的因素。有更多问题和错误的应用程序将花去多得多的时间。这是我强烈建议您尽早在性能测试环境中测试的一个原因。在开发周期中越早开始测试,您就能越早地检测到应用程序问题并正确地处理它。如果您等到开发周期快结束时才开始负载测试,那么您很可能遇到最坏的性能测试情景。

应用程序的接受标准

在任何认真的软件开发活动后,在性能测试活动开始前,应用程序必须达到性能测试接受标准。如果应用程序没有达到这些标准,那么它不应该被性能测试环境所接受:

  1. 单元测试能力。所有应用程序开发工作必须提供全面的单元测试策略和附带的可被执行的单元测试代码以确定构建是完整的和有效的。如果单元测试案例因为应用程序中的错误或缺少单元测试代码而无法被成功完成,那么应用程序不应该被性能测试所接受。
  2. 低负载级别能力。在单用户和 10 个用户负载级别上应用程序应该用去正常的计算时间来达到合理的性能和预先定义的期望。如果应用程序无法在低负载级别正常运行,那么它肯定无法在更高负载级别正常运行。开始性能测试将会浪费时间。
  3. 可用的测试数据。在性能测试期间执行应用程序所需的数据必须被提供或被详细描述以使性能测试小组能够建立与生产环境尽可能接近的副本。测试数据必须是真实的、一致的和完整的。

应用程序在以预期的行为通过性能测试前绝不能被用于生产环境。

测试规划

当性能测试环境被建立且在最佳状态运行时,下一步是制定测量被测试的应用程序的性能和特征的详细的测试计划。下面提供的信息可被用作应完成的任务和应进行的测量的清单。许多规划推荐还将指导您如何完成容量计划步骤,这些步骤能使您了解必须定义多少 JVM 才能处理生产中全部的预期的用户负载。

个别测试的持续时间

一般来说,对于个别测试,您应该只在最大负载级别上运行下面描述的个别测试和配置点,运行时间最多为 10 至 30 分钟。第一组测试运行应严格被用于在各种配置点和负载级别上收集数据。在分析了结果并确定了应用程序定义的预期的最佳配置点后,您就可以执行更长时间的测试(持续时间为 12 小时或更长)以测量长期运行的应用程序的特征。更长时间的测试还提供在指定的负载下功能和稳定性测试。

单个 JVM 和多个 JVM 的测量

性能测试有两个基本设置:单个 JVM 和多个 JVM。单个 JVM 测试在单独运行时可说明基本的应用程序性能。一些测量值(例如每秒响应的数量、servlet 响应时间和后端访问的数量)可提供预期的最大吞吐量。这些都是最大值,因为群集的环境的性能可能因后端资源的限制而难以超过单个应用程序的性能。群集的环境提供可伸缩性和故障转移。在极少数情况下,在多个 JVM 配置中可能出现在单个 JVM 配置中不可能出现的应用程序问题。

推荐:在所有的测试中,您必须既使用单个 JVM 配置,也使用群集的多个 JVM 配置。

JVM 堆大小设置

您可以使用一组从最小到最大的值来调整 JVM 堆大小设置直到找到最佳设置。servlet 引擎线程数量设置将在某种程度上决定最佳设置,这是因为每个堆栈都使用 JVM 中的内存。

推荐:通过合理地增加 JVM 堆大小设置来对它进行调整以确定应用程序的最佳内存设置。请确保 JVM 堆大小设置与同一台服务器上的任何其他应用程序不超出机器的物理内存的限制。请记住基本的操作系统也有必须被考虑的内存要求,在所有的操作系统环境中,内存交换会对应用程序性能产生负面影响。

生成的垃圾收集

针对所有操作系统平台的生成的垃圾收集(generational garbage collection)概念在 JVM V1.3 中被引入。一般来说,启用生成的垃圾收集将使积极创建许多临时对象并运行有大量用户的大容量应用程序受益。然而,可能是这种情况,也可能不是,这取决于应用程序是如何使用对象的。

请注意在性能测试期间出现的主要的垃圾收集周期的数量并理解在这些周期中对应用程序的性能含义。将导致更小的 JVM 大小的物理内存的限制常常使您看到在负载下更高的收集率。理解这里的性能影响对于在生产环境中避免意外有重要意义。与流行的看法相反,垃圾收集不会导致应用程序服务器丢失请求。

推荐:对于每一组 JVM 堆大小设置,请在一次测试的运行中启用垃圾收集,在另一次中禁用它。请您花足够的时间来运行这些测试以确保至少执行几个垃圾收集周期从而可以测量应用程序的行为。请通过观察 JVM 如何利用可用内存和用去的内存来监视垃圾收集周期。

servlet 引擎线程池

servlet 引擎线程池的大小决定了包含 Web 应用程序的 JVM 一次可执行的工作量。在 WebSphere Application Server V4.0 和更新的版本中,线程池定义了反映池大小的限制的最小值和最大值。一般来说,大容量的应用程序有较大的线程池大小,但是有些因素(例如应用程序瓶颈、synchronized 关键字的使用和/或代码中的其他限制)将阻碍大线程池的高效利用。

利用 servlet 引擎线程池的应用程序往往是使用 servlet 和 JSP 的应用程序。这也包括基于 SOAP 的应用程序。直接与 EJB 交谈的应用程序客户机不使用 servlet 线程,但的确使用 ORB 线程(请看下一部分)。

推荐:请用不同的最小和最大线程池大小来测试应用程序以确定哪些设置使应用程序完成尽可能多的工作。一般来说,为了使线程池的大小更大,您可以上调 JVM 堆大小设置,但在开始测试时请使用最小内存设置。请监视应用程序对 CPU 的利用率。一旦应用程序对 CPU 的利用率接近 80%,您将遇到 CPU 的极限,因为必须为基本的操作系统本身保留周期。

别忘了 servlet 引擎线程池的大小直接影响 Web 服务器上的 MaxClient 设置。请确保 Web 服务器有足够已定义的侦听器以避免在负载测试客户机端出现“连接失败”错误。如果确实出现了“连接失败”错误,那么 Web 服务器的侦听器的最大数量设置太低了,您必须增加它。

ORB 线程池的大小

运行于容器中的 EJB 在被分配到 ORB 线程池的线程中执行。与 EJB 通信的应用程序(这些应用程序基于远程方法调用(Remote Method Invocation,RMI)和 servlet)必须使 ORB 线程池的大小被配置。

推荐:请调整 ORB 线程池的大小。请监视线程池和 EJB 活动/响应时间以确定最佳的线程池的大小。

连接池

使用有连接池的 JDBC 资源的应用程序需要设置连接池的大小。广泛接受的实践把池中的最大连接数限制在 30-40 左右。太多的连接(连接数超过 40)不会给您带来什么好处,您应该记住每个被建立的连接消耗内存和网络资源。

会话持久数据源一般只需把最大值定义为 10 个连接。绝不要使最大的连接池大小大于 servlet 引擎线程的数量。

推荐:请调整连接池的最大值和最小值。请监视 servlet 响应时间和吞吐量(请求/秒)、JDBC 活动和内存的利用情况以达到最佳性能。

用户

您需要知道准确代表生产中应用程序的行为的性能测试活动的用户类型和数量,这一点很重要。不同的组织用不同的方法来测量用户与预期的负载之间的相关性。有些组织通过每秒 CICS 事务的数量(而不是用户的数量)来测量利用率。为了使用户负载与正确的尺度相关,您需要理解应用程序是如何利用后端资源的,这实际上是一道数学练习题。无论负载是如何被测量的,大家对最后的结果和它们表示的含义都应该有一个共同的理解。

用户的数量

用户的数量定义了应用程序所受的某个负载。因为每个应用程序很可能有不同类型的用户(例如浏览目录的用户与买东西的购物者),所以您必须使用各种情景(全部这些情景类似于平均的、预期的工作负载)来测试应用程序。

有些应用程序在高用户负载时的性能好于其他应用程序。有瓶颈问题或过多的同步的应用程序常常表现为较长的响应时间和较低的 CPU 利用率。

单用户负载测试常常被用来建立应用程序基线性能。前面已讲过,如果应用程序在单用户负载级别上表现不佳或崩溃,那么继续在更高负载级别上进行应用程序的性能测试是没用的。同样,如果应用程序在 10 个用户级别上表现不佳,那么我建议您终止测试。

一旦应用程序服务器上的 CPU 利用率接近并达到 100% 分,用户数量的增加只会导致更长的响应时间。这应该被测量和记录,因为它明确定义了应用程序的限制。这也有助于容量规划和确定群集环境中所需的应用程序克隆的数量以支持预期的负载。

用户的类型

一个应用程序常常有几个类型的用户。例如,一个卖东西的 Web 站点至少有两种类型的用户:浏览者和购物者。一种类型的用户与该站点交互但什么也不买。另一种用户执行额外的功能(例如购物和信用卡验证)。并不是所有的用户都是购物者,但所有的用户至少都是浏览者。定义参与测试的用户类型是理解站点的性能的关键。如果您预先更多地了解使用站点的各种用户,那么您所进行的性能测试将更为逼真。同样,理解常被使用的页面的流动也是有益的。这就要求负载测试脚本的开发者理解应用程序、用户类型和这些用户的正常行为。

推荐:请使用前面的所有规划推荐在以下用户负载级别上测试应用程序:1,10,100,500,800,1500 等(是否合适取决于现实的负载预期)。请监视应用程序的响应时间、吞吐量(请求/秒)、CPU 利用率、JVM 内存利用率、线程利用率和 JDBC 后端利用率。

CPU 的利用率

为了理解应用的负载对被测试的应用程序的影响,您需要记录应用程序服务器机器的 CPU 的利用率。服务器的目的在于使它达到可能的最高的 CPU 利用率。如果昂贵的服务器在运行时 CPU 的利用率仅为 20%,那么它的性价比不高。在分布式环境中,CPU 的利用率必须在预期的最大负载、硬件故障和已定义的服务质量要求之间平衡。

图 5. CPU 和响应时间
CPU 和响应时间

图 5 中的图表用蓝色显示了 CPU 的利用率,用红色显示了响应时间。一旦对 CPU 的利用达到饱和,增加的负载只会增加响应时间。您必须比较测量值与预先定义的应用程序期望以确定在哪些负载级别上可接受的响应时间才是可能的。如果应用程序有瓶颈或其他问题,这个级别对应的 CPU 利用率可能明显更低。

请测量应用程序使服务器达到饱和状态时用户负载的级别并记录它。这些数字对容量规划演习有用。

记录并评估结果

基于以上规划推荐的各种测试的执行涉及对应的保留记录的活动。只有记录了数据才能进行分析。保留记录是性能测试活动中重要的最后一步。

表 1. 样本电子表格收集了基于规划推荐的某次运行的结果。

日期/时间 2002 年 8 月 6 日 — 12:03:54
用户的数量 100
测试的持续时间(分钟) 10
Web 服务器的设置
MaxClients 600
TTL(每个进程的请求数的总和) 10,000
WebSphere Application Server 的设置
JVM 堆大小的最小值 256
JVM 堆大小的最大值 512
生成的垃圾收集 关于 -XX 设置
servlet 引擎线程池大小的最小值 10
servlet 引擎线程池大小的最大值 200
ORB 线程池大小的最小值 10
ORB 线程池大小的最大值 200
Web 服务器的测量值
CPU 的利用率(在最大时测量) 40-45 %
平均的吞吐量 0.45 秒
每秒的请求数 44.85
负载客户机的测量值
每秒的请求数 44.85
请求数的总和 7,348
成功完成的请求数 7,342
超时的请求数 4
连接失败的请求数 2
第 1 个页面的响应时间 0.35 秒
第 2 个页面的响应时间 0.54 秒
第 3 个页面的响应时间 1.33 秒
WebSphere Application Server 的测量值
servlet 的响应时间 0.28 秒
垃圾收集周期的数量 2
CPU 的利用率(在最大时测量) 33%
JDBC 每秒请求数 -- 查询 125
JDBC 的响应时间 -- 查询 37 ms
JDBC 每秒请求数 -- 插入 35
JDBC 的响应时间 -- 插入 125 ms
JDBC 每秒请求数 -- 更新 98
JDBC 的响应时间 -- 更新 222 ms

 

基于本文中给出的规划推荐的一组测试的结果与表 1 中列出的数据类似,其中记录了配置的各种元素和测得的结果。对于每个个别的测试系列,您都需要这样做。一组收集到的数据依赖于被应用程序所利用的后端资源。不直接访问 JDBC 资源的应用程序显然不会收集 JDBC 时间开销数据。您应该针对后端资源来收集基本的时间开销和频率数据。

一旦结果被收集并编译后,它们可被生成各种图表以说明应用程序的性能。结果的收集和编译可能涉及一些对数据的手工处理,因为没有一个工具能够收集所有所需的数据。

图 6. 按用户数量来显示完成的请求数
按用户数量来显示完成的请求数

图 7. 按页面和用户数量来显示响应时间
按页面和用户数量来显示响应时间

图 6 和图 7 显示了在把测试结果合并成一个电子表格后可被创建的两个可能的图表。在图形格式中,结果可以一对一地被并排放置以使其他人能够分析结果。您应该提供说明任何测量到的或观察到的异常的文本,当性能结果显著提高或下降时,您更应该这样做。

(别忘了手工维护的电子表格或数据库中可能存在人犯下的错误。为了找出可能的错误或错误的表示,您应该在数据被记录后审阅一下数据。)

数据的分析涉及找出应用程序的以下特征以确定各种最佳值:

  • servlet 响应时间和客户机响应时间
  • 网络的带宽
  • 应用程序服务器和 Web 服务器的 CPU 的利用率
  • 后端资源的利用率
  • 网络组件的利用率

一旦确定了最佳设置,您必须考虑应用程序是应该在自己的应用程序服务器上运行还是与其他应用程序一起在应用程序服务器上运行。您还必须考虑在相同的物理机器上运行的应用程序服务器的数量,因为很可能有物理资源的限制。最后,对于群集的环境,您不仅必须评估应用程序服务器机器上的物理限制,还必须评估被应用程序所利用的后端资源。所有这些因素将适用于生产环境的性能和容量规划阶段从而达到最佳性能。

性能测试的频繁程度

一个常见的误解是性能测试是一次性的工作。如果您从不更改应用程序代码或机器配置,那么性能测试是一次性的工作。然而,经常出现的情况是应用程序代码被更改或更好的机器配置被用于生产环境或这两种情况都发生了。因此,每当应用程序代码或机器配置被更改时,您必须再次执行性能测试以确定可达到最佳性能的新参数。

结束语

性能测试规划是定义、理解和执行的全面组合。在开发周期中尽早地、尽可能多地测试是在把应用程序发布到生产环境前确定性能问题的最佳方式。专门负责性能测试的小组可提供一致的测试并使个别的开发小组不必再肩负性能测试的责任。一般来说,使您深入了解 JVM 和应用程序特征的工具是物有所值的,因为它们使您快速确定问题并使性能测试活动尽可能的快速和高效。

参考资料

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号