案例研究: 调优 WebSphere Application Server V7 性能

IBM® WebSphere® Application Server 能支持的应用程序越来越多,而这些应用程序有各自的独特特性、需求和服务。正如任何两个应用程序都不会采用完全相同的方式来使用应用服务器一样,我们也无法通过一组调优参数来为任意两种不同的应用程序提供最佳性能。通常,大多数应用程序都可以通过对以下三个核心领域进行调优来实现一些性能改善:JVM、线程池和连接池。本文将通过 Apache DayTrader Peformance Benchmark Sample 应用程序来演示如何根据您应用程序所使用的主要服务器组件和资源来进行调优。 本文来自于 IBM WebSphere Developer Technical Journal

Christopher Blythe, 高级软件工程师, EMC

Christopher Blythe 于 2001 年从北卡罗莱纳州立大学 (North Carolina State University) 毕业,获得计算机工程硕士学位,之后加入位于北卡罗莱纳州三角研究工业园区 (Research Triangle Park) 的 WebSphere Application Server Performance and Benchmarking 组织。另外,由于 Christopher 对服务数据对象颇有研究,他还广泛涉及 SPECjAppServer 和 Trade 性能基准。



David Hare, 高级软件工程师, IBM  

http://www.ibm.com/developerworks/i/p-dhare.jpgDavid Hare 在位于美国北卡罗莱纳州三角研究工业园区 (Research Triangle Park) 的 WebSphere Application Server Performance and Benchmarking 组织担任高级软件工程师。在工作的 5 年时间中,David 致力于帮助客户解决与 WebSphere Application Server 相关的配置、安全性/SSL 和性能问题。他的主要研究领域是 DayTrader 性能基准测试以及部署等相关配置任务。



2009 年 11 月 23 日

简介

IBM WebSphere Application Server 是一种可靠的企业级应用服务器,它提供了一组核心组件、资源和服务,供开发人员在应用程序中使用。每个应用程序都具备特有的需求,并且经常采用截然不同的方式使用应用服务器的资源。为了提供高度灵活性并支持这种广泛的应用程序,WebSphere Application Server 提供了一组全面的参数来帮助您增强对应用程序的调优。

应用服务器已经为最常用的调优参数设置了默认值,以确保能为最广泛的应用程序提供开箱即用的性能改善。但是,由于任意两个应用程序都不可能采用完全相同的方式来使用应用服务器,因此无法确保一组调优参数能适用于所有应用程序。这也突显了对应用程序执行有重点的性能测试和调优的重要性。

本文将讨论在 WebSphere Application Server V7.0(和之前发行版)中最常使用的一些参数,以及对它们进行调优的方法。与其他相关文章提供的调优建议不同,本文将使用 Apache DayTrader Performance Benchmark Sample 案例研究作为本文的上下文。借助 DayTrader 应用程序,您可以清楚地确定所使用的主要服务器组件,对这些区域进行重点调优,并观察各种调优更改所带来的收益。

在继续阅读之前,需要记住关于应用服务器性能调优的一些事项:

  • 提高性能经常会牺牲应用程序或应用服务器的一些特性或功能。在计算性能调优更改时应该仔细考虑性能和特性之间的权衡。
  • 应用服务器之外的一些因素有时会影响性能,包括硬件和操作系统配置、系统中运行的进程、后端数据库资源的性能、网络延迟等等。您在自己执行性能评估时,必须将这些因素考虑在内。
  • 此处讨论的性能改善仅针对 DayTrader 应用程序,并且特定于此处描述的工作负载组成及所支持的硬件和软件栈。您通过本文介绍的调优更改实现的应用程序性能提升肯定会有所不同,并且应该通过您自己的性能测试进行评估。

DayTrader 应用程序

Apache DayTrader Performance Benchmark Sample 应用程序模拟了一个简单的股票交易系统,它允许用户登录/注销、查看股票组合、查询股票报价、交易股票以及管理帐户信息。DayTrader 不仅是一个优秀的功能测试应用程序,还提供了一组标准的工作负载,用于描述和测量应用服务器和组件级性能。DayTrader(以及它所依托的由 IBM 开发的 Trade Performance Benchmark Sample 应用程序)的初衷并非提供最佳性能,而是对应用服务器发行版和备选实现样式、模式进行比较。

DayTrader 基于一组核心 Java™ Enterprise Edition (Java EE) 技术,包括用于表示层的 Java servlets 和 JavaServer™ Pages (JSPs)、Java 数据库连接 (JDBC)、Java Message Service (JMS)、Enterprise JavaBeans™ (EJBs) 以及用于后端业务逻辑和持久层的消息驱动 beans (MDBs)。图 1 提供了应用程序体系结构的高级视图。

图 1. DayTrader 应用程序视图
图 1. DayTrader 应用程序视图

为了便于您评估一些常见的 Java EE 持久性和事务管理模式,DayTrader 提供了三种不同的业务服务实现。这些实现(或运行时模式)如表 1 所示。

表 1. DayTrader 实现
运行时模式模式描述
DirectServlet 到 JDBC使用自定义 JDBC 代码直接对数据库执行创建、读取、更新和删除 (CRUD) 操作。数据库连接、提交和回滚将在代码中手动管理。
Session Direct从 Servlet 到 Stateless SessionBean 到 JDBC使用自定义 JDBC 代码直接对数据库执行 CRUD 操作。数据库连接将在代码中手动管理。数据库提交和回滚将由无状态会话 bean 自动管理。
EJB从 Servlet 到 StatelessSessionBean 到 EntityBeanEJB 容器承担所有查询、事务和数据库连接的责任。

本文将讨论这些运行时模式,以便演示各种调优更改对这三种常见 Java EE 持久性和事务实现风格的影响。


导航 WebSphere Application Server 可调参数

如前所述,在执行性能调优时,理解应用程序体系结构、服务器组件以及所使用的资源是非常重要的。具备这些知识之后,您可以迅速过滤可调参数并专注于直接影响应用程序的核心可调参数。

性能调优通常从 Java Virtual Machine (JVM) 开始,它是应用服务器的基础。依照之前的观点,调优主要是由应用程序所使用的应用服务器组件所驱动。举例来说,您可以使用体系结构图(图 1)来确定 DayTrader 应用程序的一些主要可调服务器组件:

  • Web 和 EJB 容器
  • 相关线程池
  • 数据库连接池
  • 默认消息传递提供者

本文其余部分将根据上面列出的组件来详细讨论一些会对 DayTrader 性能造成影响的调优选项。这些选项可以分为以下类别:

  • 基本调优:包括一些最常调节和使用的应用服务器组件,从 JVM 开始。这些设置通常占据最大份量。
  • 高级调优:第二种高级调优参数通常与特定的场景相关,且常用于发掘系统的最大性能。
  • 异步消息传递调优:此处讨论的选项特定于使用 WebSphere Application Server 的消息传递组件实现异步消息传递的应用程序。

我们将详细讨论这类调优参数的适用性,它们的功能权衡以及最终对性能造成的影响(如果可能,针对各种持久性和事务管理模式)。我们还将介绍可以在调优过程中为特定参数提供协助的一些工具。各小节还将提供相关 WebSphere Application Server Information Center 文档或其他相关资源的链接,并最终将汇总在 参考资料 小节中。


基本调优

本节将讨论:

  1. JVM 堆大小
  2. 线程工具大小
  3. 连接池大小
  4. 数据源状态缓存大小
  5. 通过引用传递的 ORB

a. JVM 堆大小

JVM 堆大小参数将直接影响垃圾收集行为。通过增加 JVM 堆大小,可以在出现分配故障并触发垃圾收集之前创建更多对象。这通常可以让应用程序增加各垃圾收集 (GC) 周期之间的间隔时间。遗憾的是,增加堆大小的一个缺点是查找和处理需要垃圾收集的对象所需的时间也会随之增加。因此,JVM 堆大小调优经常涉及确定垃圾收集之间的间隔时间与执行垃圾收集所需的暂停时间之间的平衡点。

要对 JVM 堆大小进行调优,需要启用详细模式的(verbose)GC。此操作可以在 WebSphere Application Server 管理控制台中完成:依次选择 Servers => Application servers => server_name => Process definition => Java Virtual Machine。通过启用详细模式的 GC,JVM 在每次垃圾收集时都会打印输出有用的信息,比如堆中的空闲和已使用字节、垃圾收集之间的间隔以及暂停时间。这些信息将记录在 native_stderr.log 文件中。随后,各种工具可以使用该文件来可视化堆使用情况。

WebSphere Application Server 的默认堆设置如下:初始堆大小为 50 MB,最大堆大小为 256 MB。通常情况下,应该将最小和最大堆大小设置为相同值,以防止 JVM 动态调整堆设置。通过将重要参数固定为常量,这不仅有助于简化 GC 分析,还可以避免与分配和取消分配更多内存相关的成本开销。将最大和最小堆大小设置为相同值的缺点在于,初次启动 JVM 时会比较慢,因为 JVM 必须分配更大的堆。

在一些场景中,将最大和最小堆大小设置为不同值是更有利的。其中一个场景就是运行不同工作负载的多个应用服务器实例托管在同一服务器上。在此场景中,JVM 可以动态响应不断变化的工作负载需求,并更加高效地使用系统内存。

测试

在启动详细模式 GC 的情况下,我们针对初始和最大堆大小分别设置为 256 MB、512 MB、1024 MB 和 2048 MB 执行了 4 次测试。您可以手动分析详细模式 GC,但可以通过一些图形工具,比如 IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer 工具(随可免费下载的 IBM Support Assistant 附带),可以显著简化此过程。该工具用于在实验测试中查看详细模式 GC 数据,以便在查找 DayTrader 应用程序的适当堆大小时可以做出一些调整。

在详细模式垃圾收集输出中监视的第一批项目包括收集后的空闲堆。该指标常用于确定应用程序中是否出现的任何 Java 内存泄漏。如果此指标未达到稳定状态值,并随时间持续减小,则明确表示应用程序中出现了内存泄漏。收集后的空闲堆指标还可以与堆大小结合,共同计算服务器和应用程序所使用的内存工作集(或 “内存占用”)。只需要从总堆大小中减去空闲堆值就可以得到这个值。

图 2. 收集后的空闲堆汇总
图 2. 收集后的空闲堆汇总

需要注意,虽然详细模式 GC 数据和图 2 中的表可以帮助检测 Java 堆中的内存泄漏,但无法检测本机内存泄漏。发生本机内存泄漏的情况是本机组件(比如使用 C/C++ 编写并通过 Java Native Interface API 调用的供应商本机库)造成本机内存泄漏到 Java 堆外部。在这种情况下,需要使用平台相关工具(如 Linux® 平台上的 pstop 命令、Windows® 平台上的 Perfmon 命令等)来监控 Java 进程的本机内存使用。WebSphere Application Server Support 分页 提供了关于诊断内存泄漏的详细文档。

另外还需要考虑各收集任务的垃圾收集间隔时间平均暂停时间。GC 间隔时间是垃圾收集周期之间的间隔时间。暂停时间是垃圾收集周期完成所需的时间。图 3 展示了四种堆大小的垃圾收集间隔时间。它们最终的平均值是 0.6 秒 (256 MB)、1.5 秒 (512 MB)、3.2 秒 (1024 MB) 和 6.7 秒 (2048 MB)。

图 3. 垃圾收集间隔时间
图 3. 垃圾收集间隔时间

图 4 显示了四种堆大小的平均暂停时间。在实验测试中,它们最终的平均值分别是 62 ms (256 MB)、69 ms (512 MB)、83 ms (1024 MB) 和 117 ms (2048 MB)。这明确展示了增加 Java 堆大小的标准权衡。当堆大小增加时,GC 之间的间隔将增加,这样便可以在 JVM 暂停以执行垃圾收集例程之前完成更多任务。但是,增加堆大小还意味着垃圾收集器必须处理更多对象,从而能增加 GC 暂停时间。

图 4. 平均暂停时间
图 4. 平均暂停时间

GC 间隔和暂停时间共同构成了垃圾收集所耗费的时间。垃圾收集所花费的时间百分比将显示在 IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer 工具中,并且可以使用以下公开计算得出:

垃圾收费所耗费的时间面分比

各种情况下垃圾收集所占用的时间以及形成的吞吐量(每秒请求数)如图 5 所示。

图 5. 垃圾收集所战用的时间和吞吐量
图 5. 垃圾收集所战用的时间和吞吐量

建议将 DayTrader 应用程序的初始和最大堆大小设置为 1024 MB。至此,您的边际收益将开始逐渐递减,因为进一步增加堆大小将不会带来成比例的性能改进。这在较长垃圾收集间隔时间与较短暂停时间之间达到了平衡,从而减少了垃圾收集所花费的时间。

JVM 调优的另一个重要方面是垃圾收集策略。三种主要的 GC 策略如下:

  • optthruput:(默认)当应用程序暂停时,在垃圾收集过程中执行标记和清扫操作,以便最大限度提高应用程序吞吐量。
  • optavgpause:在应用程序运行时并发执行标记和清扫操作,以便最大限度缩短暂停时间;这将提供最理想的应用程序响应时间。
  • gencon:区别对待短期和长期对象,同时提供较短的暂停时间和较高的应用程序吞吐量。

DayTrader 应用程序并未使用许多长期对象,并且在使用默认的 GC 策略时性能最佳。但是,应用程序是各不相同时,因此您应该评估各 GC 策略,以便找到最适合您应用程序的策略。developerWorks 文章 垃圾收集策略 提供了关于 GC 策略的更多信息。

图 6 展示了通过在各种不同的 DayTrader 运行时模式下调优 JVM 堆大小所实现的性能提升。在该表中,蓝柱用于表示基准吞吐量值,而红柱表示调整所讨论的调优参数后的吞吐量值。为了便于各种运行时模式之间的相对吞吐量差异,所有度量都将与 EJB 模式基准进行比较。

举例来说,在调优之前,Session Direct 和 Direct 模式分别比 EJB 模式基准快 23% 和 86%。第二根轴上的线表示 各运行时模式下的总体性能改善。在本例中,JVM 调优为三种运行时模式带来了不同程度的改善,因为它们分别采用所特有的对象分配模式。性能改善的范围从 3%(JDBC 模式)到 9%(EJB 模式)不等。

这方面的信息将在结束对各调优参数的讨论时给出。根据上一节所提供的参数,调节各调优参数后实现的应用程序性能改善是可以累加的。本文结尾部分提供的表(图 22)列出了可用的所有调优更改带来的总体性能改善。

图 6. 调优 JVM 堆大小带来的性能改进
图 6. 调优 JVM 堆大小带来的性能改进

更多信息:

b. 线程池大小

服务器执行的各项任务运行于 WebSphere Application Server 的许多线程池中的某个线程之上。线程池允许服务器的组件重用线程,从而避免了在运行时创建新线程来服务各个新请求。应用服务器中最常用(和调优)的三个线程池如下:

  • Web 容器:当请求通过 HTTP 传入时使用。在 DayTrader 体系结构图(图 1)中,可以看到大多数流量都通过 Web Container 流入了 DayTrader。
  • 默认:当针对消息驱动 bean 的请求传入时,或者没有为特定传输链定义具体线程池时使用。
  • ORB:当针对企业 bean 的请求从 EJB 应用程序客户机、远程 EJB 接口或另一台应用服务器通过 RMI/IIOP 传入时使用。

与线程池相关的重要调优选项如表 2 所示。

表 2. 可调优的线程池选项
设置描述
最小大小池中准许的最大线程数量。当应用服务器启动时,最初不会向线程池分配任何线程。线程将作为分配给需要它们的应用程序服务器的工作负载被添加到线程池中,直到池中的线程数量等于在最小大小字段中指定的数值。此后随着工作负载的变化还会添加和删除一些线程。但是,池中的线程数量从来都不会低于在最小大小字段中指定的数值,即便其中一些线程是空闲的。
最大大小指定默认线程池中的最大线程数量。
线程静止超时指定回收线程之前应该间隔的静止时间(毫秒)。值为 0 表示无需等待,负值(小于 0)则表示永远等待。

假定机器包含一个应用服务器实例,则一个良好的实践是每个服务器 CPU 核心为默认线程池使用 5 个线程,每个服务器 CPU 为 ORB 和 Web 容器线程池使用 10 个线程。对于 CPU 多于 4 个的机器,默认设置通常可以满足大多数应用程序的需求。如果机器有多个应用服务器实例,则这些相应地减小这些值的大小。相反,有时也需要增加线程池大小来解决应对 I/O 较慢或后端连接需要长时间运行的问题。表 3 列出了最常调优的线程池的默认线程池大小和静止超时。

表 3. 默认线程池大小和静止超时
线程池最小大小最大大小静止超时
默认20205000 ms
ORB10503500 ms
Web 容器505060000 ms

要修改线程池设置,可以在管理控制台中导航到 Servers => Application Servers => server_name => Thread Pool。您还可以使用 Performance Advisors 来获得关于线程池大小和其他设置的建议。

IBM Tivoli® Performance Viewer 是嵌入在管理控制台中的一款工具,它允许您查看几乎任何服务器组件的性能监控基础设施(Performance Monitoring Infrastructure,PMI)数据。查看器将提供建议帮助用户调优系统,并针对效率低下的设置提供一些可行的备选建议。访问 WebSphere Application Server Information Center,了解如何使用 Tivoli Performance Viewer 来启动和查看 PMI 数据。

图 7 展示了当 DayTrader 应用程序启动并在稳定、峰值负载下运行时 Web container 线程池的 PMI 数据。池大小(黄色)是池中线程数量的平均值,而活动计数(红色)是当前活动线程的数量。从这个图中可以看出,默认设置,即最多 50 个 Web 容器线程,最适合这种情况,因为所有 50 个线程都未被分配,并且并发工作负载平均使用大约 18 个线程。由于默认线程池大小已经足够,因此不需要对线程池大小进行修改。

图 7. Web 容器线程池的 PMI 数据
图 7. Web 容器线程池的 PMI 数据

在 WebSphere Application Server V6.x 之前,并发客户机连接与 Web 容器线程池中的线程之间存在一一对应的关系。换句话说,如果有 40 个客户机在访问应用程序,则有 40 个线程需要服务请求。在 WebSphere Application Server V6.0 和 6.1 中,由于引入了 Native IO (NIO) 和 Asynchronous IO (AIO),因此能够使用相对较少的线程来扩展数千客户连接。这解释了为何在图 7 中平均只使用 18 个线程来服务来自 HTTP 负载驱动程序的 50 个并发客户机连接。根据此信息,可以减小线程池大小,以便降低管理大小超过需要的线程池的开源。但是,这会影响服务器响应负载峰值(这时需要大量线程)的能力。应该通过仔细考虑来确定线程池的大小,包括预期的平均和峰值工作负载。

c. 连接池大小

每次当应用程序尝试访问后端库时(比如数据库),它都需要资源来创建、维持和释放到该数据库的连接。为了缓解此过程对总体应用程序资源的压力,应用服务器允许您建立一个后端连接池,用于在应用服务器上共享应用程序。连接池将连接开销分散分布在若干用户请求中,以便保留应用程序资源供未来请求使用。与连接池相关的重要调优选项如表 4 所示。

表 4. 连接池调优选项
设置描述
最少连接数要维持的最少物理连接数量。如果连接池的大小小于或等于最小连接池大小,则 未使用的超时线程(unused timeout thread) 将不会放弃物理连接。但是,池并不会单独创建连接来确保维持了最小连接池大小。
最大连接可以在这个池中创建的物理连接的最大数量。它们是到后端数据库的物理连接。达到这个数值时,将不会再创建新的物理连接;请求者必须等待直到当前使用的某物理连接返回到池中,或者直到抛出一个 ConnectionWaitTimeoutException 异常(均基于连接超时设置)。设置较高的最大连接值有时会造成连接请求淹没您的后端资源。
线程静止超时指定在线程回收之前应该等待的静止时间(毫秒)。值为 0 表示不需要等待,负值(小于 0)则表示永远等待。

调优连接池的目标是确保各线程都有一个数据库连接,并且请求不需要排队以等待访问数据库。对于 DayTrader 应用程序来说,每个任务都需要对数据库执行一次查询。由于每个线程都需要执行一个任务,因此各并发线程都需要一个数据库连接。通常,通过 HTTP 传入的所有请求都将在 Web 容器线程上执行。因此,最大连接池大小至少应该达到 Web 容器线程池的最大大小。但是,有时请求会传入到默认的线程池中,比如通过消息传递 beans 的异步模式。

总的来说,通用的最佳实践是确定哪些线程池服务任务需要 DataSource 连接并相应调节池的大小。在本例中,最大连接池大小被设置为默认和 Web 容器线程池的最大大小 (70)。要修改连接池设置,可以在管理控制台中导航到 Resources => JDBC => Data Sources => data_source => Connection pool properties。记住,从连接管理的角度来看,所有应用程序都不能具有 DayTrader 那么优异的表现,因此可以为一个线程使用多个连接。

图 8 显示了 DayTrader 在稳定状态峰值负载下使用默认连接池大小(1 最小/10 最大)运行时连接池的 PMI 数据。FreePoolSize(黄色)是池中空闲连接的数量,而 UseTime(绿色)是连接所使用的平均时间(毫秒)。从此图中可以看出所有 10 个连接始终都在使用中。除了表格指标之外,该表还显示其他一些重要指标:WaitingThreadCount 显示 33 个线程等待数据库连接的平均 WaitTime 为 8.25 ms,并且 PercentUsed 指标表明池的总体占用率为 100%。

图 8. 调优连接池之前 PMI 指标
图 8. 调优连接池之前 PMI 指标

图 9 显示了将连接池大小调优为 10(最小)/70(最大)后的同一表。这表明有大量空闲连接可用,且没有线程在等待连接,从而实现了更快的响应速度。

图 9. 调优连接池后的 PMI 指标
图 9. 调优连接池后的 PMI 指标
图 10. 调优连接池大小后的性能改进
图 10. 调优连接池大小后的性能改进

更多信息:

d. 数据源语句缓存大小

数据源语句缓存大小指定每次连接可以缓存的经过准备的 JDBC 语句的数量。WebSphere Application Server 数据源将优化经过准备的语句和可调用的语句,它可以缓存未在活动连接中使用的语句。如果您的应用程序像 DayTrader 那样使用许多语句,则增加此参数有时可以改善应用程序性能。要配置语句缓存大小,可以导航到 Resources => JDBC => Data sources => data_source => WebSphere Application Server data source properties

可以使用一些不同的方法来调优数据库语句缓存大小。其中一个技巧就是审查所有独特的、经过准备的语句的应用程序代码(或从数据库或数据库驱动程序收集到的 SQL 跟踪),并确保缓存大小大于该值。其一种方法是迭代式的增加缓存大小并在峰值稳定状态负载下运行应用程序,直到 PMI 指标不再报告任何缓存丢弃操作。图 11 展示了连接池的相同 PMI 表,这次数据库语句缓存大小从默认值 (即 10)增加到了 60。PrepStmtCacheDiscardCount 指标(红色)表示由于缓存已满而被丢弃的语句的数量。回过头来看图 9 中的表,在调优数据源语句缓存大小之前,被丢弃的语句的数量超过 170 万条。而图 11 显示,调优缓存大小后再也没有出现丢弃语句的情况。

图 11. 调优数据源语句缓存大小之后的 PMI 指标
图 11. 调优数据源语句缓存大小之后的 PMI 指标
图 12. 增加数据源语句缓存大小之后的性能改进
图 12. 增加数据源语句缓存大小之后的性能改进

更多信息:

e. ORB 通过引用传递

Object Request Broker (ORB) 通过引用传递选项确定,在处理 EJB 请求中涉及的参数对象时应该使用通过引用传递还是通过值传递语义。要找到此选项,在管理控制台中导航到 Servers => Application Servers => server_name => Object Request Broker (ORB)。默认情况下,此选项是禁用的,并且将各参数对象的副本传递给调用的 EJB 方法。与向已有参数对象传递简单的引用相比,这种方式的开销要高很多。

总的来说,ORB 通过引用传递选项基本上将调用的 EJB 方法作为本地调用对待(甚至对于带远程接口的 EJB),并避免必需的对象复制操作。如果远程接口不是绝对必需的,则一种稍微简单的、不需要调优的替代方案就是使用带本地接口的 EJB。但是,使用本地而不是远程接口,您会损失与远程接口、分布式环境中的位置透明性以及工作负载管理功能相关的一些收益。

仅当 EJB 客户机(即 servlet)和所调用的 EJB 模块位于相同的类加载器中时,ORB 通过引用传递选项才能够带来收益。这一需求意味着 EJB 客户机和 EJB 模块必须部署在相同的 EAR 文件中,并在相同的应用服务器实例中运行。如果 EJB 客户机和 EJB 模块被映射到不同的应用服务器实例(通常表示为 split-tier),则必须使用通过值传递的语义来远程调用 EJB 模块。

由于 DayTrader 应用程序在相同的 EAR 中包含 WEB 和 EJB 模块,并且两者都将被部署到相同的应用服务器实例中,因此 ORB 通过引用传递选项可用于实现性能提升。从图 13 中的度量可以看出,此选项让 DayTrader 从中显著受益,来自 servlet 的所有请求都将通过远程接口传递给无状态会话 bean。但直接模式除外,这时 EJB 容器会绕道采用直接 JDBC 和手动事务。

图 13. ORB 通过引用传递的性能改进
图 13. ORB 通过引用传递的性能改进

更多信息:


高级调优

讨论要点:

  1. Servlet 缓存
  2. HTTP 传输持久性连接
  3. 大分页支持
  4. 禁用未使用的服务
  5. Web 服务器位置

a. Servlet 缓存

WebSphere Application Server 的 DynaCache 为服务器所生成的对象和分页分段提供了一个通用的内存缓存服务。DistributedMap 和 DistributedObjectCache 接口可以在应用程序中用于缓存和共享 Java 对象,其方法是将引用存储到缓存中的这些对象中以便随后使用。另一方面,Servlet 缓存使 servlet 和 JSP 响应分段能由一组可定制的缓存规则来存储和管理。

在 DayTrader 应用程序中,每次访问用户的主页时都会显示一个 Market Summary。该摘要信息包含股票涨跌榜的前 5 名和后 5 名,以及当前的股票索引和交易量。此活动需要执行一些数据库查询操作,因此会造成加载用户主页出现显著延时。借助 servlet 缓存,marketSummary.jsp 可以保存在缓存中,这可以从基本上避免这些开销大的数据库查询操作,从而改善用户主页的响应速度。可以配置缓存对象的刷新间隔,清单 1 中的示例将该值设定为了 60 秒。Dynacache 还可以用于缓存 DayTrader 中的其他 servlet/JSP 分段和数据。本例将演示通过缓存来避免复杂的服务器操作可以实现哪些改善。

要启用 Servlet 缓存,在管理控制台中导航到 Servers => Application servers => server_name => Web container settings => Web container。必须在 cachespec.xml 文件定义到要缓存的 servlet 或 JSP 的 URI 路径,该文件位于 Web 模拟的 WEB-INF 目录中。对于 DayTrader 中的 marketSummary.jsp 来说,cachespec.xml 的内容与清单 1 相似。

清单 1. cachespec.xml
清单 1. cachespec.xml
图 14. servlet 缓存的性能改进
图 14. servlet 缓存的性能改进

更多信息:

b. HTTP 传输持久连接

持久连接指定传出的 HTTP 响应应该使用持久(保持活动状态)连接,而不是在请求或响应交换后关闭的连接。在许多情况下,可以通过单一 HTTP 连接许可的持久请求的最大数量来实现性能提升。通过让每个连接可支持的持久请求不受限制,SSL 连接可以显著的性能改进,因为 SSL 连接会导致通过交换键和协调协议来完成 SSL 握手过程,从而增加开销。通过最大限度地增加每个连接可处理的请求数量,可以最大限度地减小此开销的影响。另外,通过保持连接为打开状态,而不是针对各请求打开或关闭连接,响应速度快的高吞吐量的应用程序也可以实现性能提升。当此属性设置为 0(零)时,连接将在应用服务器运行过程中一直保持为打开状态。但是,如果涉及到安全性问题,则应该仔细考虑这项设置,因为当客户机尝试建立始终活动的连接时,此参数可以帮助防止拒绝访问攻击。

可以在管理控制台中设置 HTTP 传输持久连接,方法是导航到 Servers => Application servers => server_name => Ports。然后,单击与要更改的 HTTP 传输渠道设置相关的端口的 View associated transports

在 DayTrader 测试的过程中,每个连接的最大持久请求数量(Maximum persistent requests per connection)的值从 100(默认)更改为不受限制。图 15 中的表显示了通过 HTTP(非 SSL)和 HTTPS(SSL)访问简单的 “Hello World” servlet 的吞吐量结果(在将每个连接的最大持久请求数量设置为不受限制之前和之后)。

图 15. 将每个连接的请求数量设置为不受限制之前带来的性能改进
图 15. 将每个连接的请求数量设置为不受限制之前带来的性能改进

更多信息:

c. 大分页支持

一些平台支持建立一大块相邻的内存区,以便能够使用比默认内存分页大小更大的内存分页。根据所使用的平台,大内存分页大小可以从 4 MB (Windows) 到 16 MB (AIX) 不等,而默认分页大小只有 4 KB。许多应用程序(包括基于 Java 的应用程序)经常能大分页中受益,因为要管理的大分页减少有助于降低 CPU 开销。

要使用大内存分页,首先需要在操作系统中定义并启用它们。各平台的系统需求也相互不同,必须在可以启用大分页支持之前配置好它们。WebSphere Application Server Information Center 提供了在平台中完成此任务的详细步骤:

在操作系统中完成配置之后,可以在 JVM 中启动大分页支持,方法是在管理控制台的 Servers => Application servers => server_name => Process definition => Java Virtual Machine 中指定 Generic JVM Arguments 设置的 -Xlp。需要注意,如果启用了大分页,则操作系统会留出一大块相阾的内存区供 JVM 使用。如果剩余内存不足以处理其他正在运行的应用程序,则会换出分页(即将内存中的分页换出到硬盘上的分页),这会显著降低系统性能。

图 16. 大分页的性能改进
图 16. 大分页的性能改进

更多信息:

d. 禁用未使用的服务

禁用应用程序不需要的、未使用的服务可以改善性能。PMI 就是一个典型的例子。需要重点注意,必须启用 PMI 以便查看本文之前记录的指标并从性能审查程序获取建议。虽然禁用 PMI 会移除查看此信息的功能,但它也提供了少许性能改进。可以为各应用服务器禁用 PMI,方法是在管理控制台中导航到 Monitoring and Tuning => Performance Monitoring Infrastructure (PMI)

图 17. 禁用 PMI 的性能改进
图 17. 禁用 PMI 的性能改进

更多信息:

e. Web 服务器位置

IBM HTTP Server 等 Web 服务器通常用于在 WebSphere Application Server 部署中处理静态内容,或提供工作负载管理 (WLM) 功能。在 V6 之前的 WebSphere Application Server 版本中,还需要借助 Web 服务器来有效处理数以千计的传入客户机连接,其原因归结为客户机连接与 Web 线程之间的 “一对一” 映像关系(之前讨论过)。在 WebSphere Application Server V6 及更高版本中,NIO 和 AIO 的引入免除这些需求。对于使用 Web 服务器的环境,应该将 Web 服务器实例置于不同于 WebSphere Application Server 实例的专用系统上。如果某 Web 服务器所在系统上有一个 WebSphere Application Server 实例,则它们将有效共享有价值的处理器资源,从而降低配置的总体吞吐量。

我们将 IBM HTTP Server 与 WebSphere Application Server 放置在同一台本地机器上执行了 DayTrader 测试,然后又将 Web 服务器置于远程专用机器上执行了第二次测试。表 5 显示了 Web 服务器和应用服务器置于相同系统上时各进程点用的 CPU 周期百分比。从结果中可以看出,HTTP Server 进程占用了大约 25% 的 CPU 周期,这对应此测试中所使用的 4-CPU 系统中的 1 个 CPU。

表 5. HTTP Server 的 CPU 利用率
进程CPU %
WebSphere Application Server66.3
IBM HTTP Server26.2

图18 比较了这两个场景以及完全没有 Web 服务器的情况下的吞吐量和响应时间。

图 18. 使用或未使用 Web 服务器时的吞吐量
图 18. 使用或未使用 Web 服务器时的吞吐量

异步消息传递调优

目前为止,本文的侧重点主要是 DayTrader 应用程序和 WebSphere Application Server 的核心 Web 服务和持久性方面。现在,我们将重点转到 DayTrader 如何使用 JMS 组件来执行异步处理或交易订单和监控报价变化。DayTrader 基准测试应用程序包含两个可单独启用或禁用的消息传递特性:

  • 异步订单处理:异步订单交易处理将由一个 JMS 队列和一个 MDB 来处理。
  • 报价一致性跟踪:一个 JMS 话题,并且 MDB 将用于监控与股票交易订单相关的报价变化。

消息传递配置有两个主要调优选项会对性能造成显著影响:消息库类型和消息可靠性。除此之外,一种更加高级的、能实现额外性能改进的调优技巧是将事务日志和文件库(如果可用)放置在速度较快的磁盘上。各主题以及相应的性能改进将在下面详细讨论。

讨论要点。

  1. 消息库类型
  2. 消息可靠性水平
  3. 将事务日志和文件库移动到快速磁盘上

a. 消息库类型

WebSphere Application Server 的内部消息传递提供者维持消息传递引擎“数据库”的概念。数据库充当由引擎处理的消息的持久存储库。在单服务器环境中创建了一个消息传递引擎之后,系统会创建一个基于文件的库来作为默认数据库使用。在 WebSphere Application Server V6.0.x 中,默认数据库将由一个本地的 in-process Derby 数据库提供。基于文件和 Derby 的数据库非常适用于单服务器场景,但不能提供最高水平的性能、可伸缩性、可管理性或高可用性。要满足这些需求,可以使用一个远程数据库数据暂存器:

  • 本地 Derby 数据库数据暂存器:通过此选项,可以使用一个本地 in-process Derby 数据库来存储操作信息以及与消息传递引擎相关的消息。虽然适用于开发目的,但此配置需要使用应用服务器中的宝贵 CPU 周期和内存来管理存档的消息。
  • 基于文件的数据暂存器:(默认)如果配置消息引擎使用基于文件的数据暂存器,则操作信息和消息将持久化到文件系统中,而不是数据库中。其执行速度比本地 Derby 数据库更快。并且,如果使用了快速硬盘,比如独立磁盘冗余阵列(RAID),其执行速度可以与远程数据库相媲美。下面显示的测试结果并未使用 RAID 设备作为基于文件的数据暂存器,并且未返回此额外改善。
  • 远程数据库数据暂存器:在此配置中,远程系统中的数据库将充当消息引擎数据暂存器。这将释放应用服务器 JVM 进程占用的之前用于管理 Derby 数据库基于文件的暂存器的 CPU 周期,从而允许使用一个性能更加出众的生产级数据库服务器(比如 IBM DB2® Enterprise Server)。使用数据库作为数据暂存器在技术方面的一个优势是,一些 J2EE™ 应用程序可以共享 JDBC 连接,从而受益于单相提交优化。请参见关于通过共享连接获取单相提交优化收益的更多信息。文件暂存器不支持这种优化。

DayTrader 使用这三种不同的消息暂存类型运行于 EJB 异步模式之下。在运行过程中,我们启用了跟踪规范 org.apache.geronimo.samples.daytrader.util.Log=all 来捕获接收 TradeBrokerMDB 消息的所用的时间。在测量异步消息传递性能时,让度量以异步 MDB 响应时间为基础为非常重要的 —— 而不是实际的同步分页响应时间。图 19 中的结果表明,远程数据库数据暂存器能实现最佳性能,因为它提供了最短的 MDB 响应时间和最高的吞吐量。

图 19. 消息暂存器类型性能比较
图 19. 消息暂存器类型性能比较

更多信息:

b. 消息可靠性水平

消息的可靠性对于任何消息传递系统来说都是一个非常重要的因素。WebSphere Application Server 消息传递提供者提供了 5 种不水平的可靠性:

  • 尽可能保证非持久性(Best effort non-persistent)
  • 极速非持久性(Express non-persistent)
  • 可靠的非持久性(Reliable non-persistent)
  • 可靠的持久性(Reliable persistent)
  • 可以保证的持久性(Assured persistent)

持久消息始终会保存到某种形式的持久化数据暂存器中,而非持久化消息通常存储在易变内存中。消息交付的可靠的和交付该消息的速度之间是一种权衡关系。图 20 显示了使用可靠性水平不同(可以保证的持久性和极速非持久性)的文件暂存器的两种测试的结果。结果清楚地显示,随着可靠水平提高,处理消息的速度会变得更快。

图 20. 消息可靠性水平的性能比较
图 20. 消息可靠性水平的性能比较

更多信息:

c. 将事务日志和文件暂存器移动到快速磁盘

由于磁盘 I/O 操作开销较大,因此将日志文件存储在 RAID 这样的磁盘上可以显著改善性能。在大多数 RAID 配置中,将数据写入到物理媒介中的任务将由多个驱动器共享。此技巧产生的结果是会更多地采用的并发的方式来访问存储以持久化事务信息,以便更快地访问日志中的数据。

可以在管理控制台中设置事务日志目录,方法是导航到 Servers => Application Servers => server_name => Container Services => Transaction Service

在创建 SIBus 成员的过程中,可以使用 AdminTask addSIBusMember 中的 -logDirectory 选项,或者通过管理控制台 SIBus Member 创建面板来指定文件暂存器日志目录(File store log directory)

图 21 显示了两种测试的运行结果:一个测试将事务日志和文件暂存器存储在本地硬盘上,而另一个测试将它们存储在一个 RAMDisk 上(这会从本质上将内存区作为硬盘对待,以实现更快的读取和写入操作)。运行测试时,我们使用了极速非持久性可靠性水平。结果表明,将日志存储在快速磁盘上时,响应时间和吞吐量指标较高。

图 21. 使用快速磁盘的性能改进
图 21. 使用快速磁盘的性能改进

更多信息:


结束语

IBM WebSphere Application Server 的宗旨是能够满足应用程序不断增加的需求,并且这些应用程序有各自的独特特性、需求和服务。这种灵活性也承认了这样一个事实:任意两个应用程序都不会采用完全相同的的方式来使用应用服务器,同时也没有一组调优参数可以为任意两个不同的应用程序提供最佳的性能。

虽然 DayTrader 可能不同于您的应用程序,但判定采用何种调优的方法是相同的。关键是根据应用程序体系结构确定并专注于应用程序所使用的主要服务器组件和资源。通常而言,许多应用程序都可以通过调优以下三个核心区域实现一定程度的性能改进:JVM、线程池和连接池。其他一些可以调优的参数也能实现非凡的效果;但是,它们通常涉及应用程序所使用的具体 WebSphere Application Server 特性。

本文讨论了这些可以调优的核心参数,以及其他一些能让 DayTrader 应用程序获益的选项。对于这些选项,我们都提供了找到它们的方法,提供了一些通用建议和要注意的权衡事项,并了指明了相关工具。图 22 显示了应用这些调优选项之后每个 DayTrader 运行时模式的总体性能改善:

  • JVM 堆大小
  • 线程池大小
  • 连接池大小
  • 数据源语句缓存大小
  • ORB 通过引用传递
  • Servlet 缓存
  • 不受限制的持久性 HTTP 连接
  • 大分页支持
  • 禁用 PMI
图 22. 应用调优选项之后的总体性能改善
图 22. 应用调优选项之后的总体性能改善

从图中可以明确看出,本文所述调优在 EJB 模式下实现了 169% 的改善,在 Session Direct 模式下实现了 207% 的改善,并在 Direct 模式下实现了 171% 的改善。这是相当可观的改善,并且在其他应用程序中也可以实现类似的改善;但是,您必须记住最终的结果会因本文所述因素以及其他一些因素而异。

希望本文所讨论的信息和工具能帮助您更加轻松地调优特定应用程序的应用服务器。

参考资料

学习

获得产品和技术

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=449098
ArticleTitle=案例研究: 调优 WebSphere Application Server V7 性能
publish-date=11232009