中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> IBM专区 > DB2 > 性能
DB2 Content Manager Web 应用程序
作者:佚名 时间:2005-08-10 17:51 出处:互连网 责编:小渔
              摘要:DB2 Content Manager Web 应用程序
性能调优和调试方法

级别: 高级

Chitrang Shah
DB2 Content Manager 开发人员, IBM
2004 年 9 月

对了解更多关于 J2EE 应用程序性能调优技术和调试方法方面的知识感兴趣吗?本文集中讨论在 IBM ® DB2® Content Manager V8.x 上开发的 J2EE™ 应用程序的高级体系结构,同时还介绍了对网络进行排队、识别排队网络中的关键组件、列出排队网络中每个组件的关键调优参数等概念。本文还探讨了 JVM “垃圾收集”和调优参数的影响。

简介
本文重点讨论在 IBM DB2 Content Manager V8.x 上开发的 J2EE™ 应用程序的性能调优技术和调试方法。尽管大部分技术和方法源自对 DB2 Content Manager eClient 8.x 的性能测试,但是它们同样适用于 DB2 Content Manager 上的所有 J2EE 应用程序。

本文的焦点是 J2EE 应用程序的高级体系结构,同时还介绍了对网络进行排队、识别排队网络中的关键组件、列出排队网络中每个组件的关键调优参数等概念。我们还探究了 JVM “垃圾收集”和调优参数的影响。最后,本文重点讨论了如何识别三种不同类型的性能目标,以及它们的调优和调试方法。

J2EE 应用程序的体系结构
如下图所示,HTTP 请求是作为用户操作(单击链接、按钮等)的结果由浏览器发出的。Web 服务器接收该请求,并将它转发给 Web 服务器插件,然后,由该插件识别应该为请求提供服务的 Web 容器。接收请求的 Web 服务器会分配一个 Java 线程,以执行请求并调用适当的 servlet。然后,servlet 又调用适当的 Content Manager API,再由该 API 返回 DDO/XDO 对象。DB2 Content Manager API 在内部使用一个 JDBC™ 连接池与 DB2 Content Manager 服务器进行通信。然后,请求被转发给 Java 服务器页面(JSP)。该 JSP 使用 DDO/XDO 对象生成一个动态 HTML 页面。这些 DDO/XDO 对象可能被应用程序缓存以便将来使用,也可能不被缓存。

J2EE 应用程序的体系结构
WebSphere 的体系结构

如上所述,在处理请求期间,请求是通过各种组件传递的。这些组件组合在一起形成了一个排队网络。要优化应用程序的性能,就应该试着最小化每个组件的等待时间。

WebSphere 排队网络
J2EE 应用程序的体系结构

每个组件的调优参数
我们没有提供有关调优参数的所有细节以及这些参数的建议值,而是重点描述了这些参数对应用程序的性能和可伸缩性的影响。请参阅 eClient 8.2 Tuning Guide ,以获得关于这些参数的建议值的信息。

Web 服务器

  • KeepAlive:
    该参数用于控制,当 Web 服务器为请求提供服务之后,是否还应该让到浏览器的连接继续处于活动状态。通过让连接继续处于活动状态,可以省去建立新连接的开销,从而使浏览器可以更快地为以后的请求提供服务。同时,这样做也会增加 Web 服务器对资源的使用。
  • MaxKeepAliveRequests:
    该参数控制到某台 Web 服务器的活动连接的最大数量。活动连接的数量越大,允许继续处于活动状态的浏览器就越多,从而增加了响应请求的次数。但是,正如前面所提到的,这样做也会增加 Web 服务器对资源的使用。
  • MaxRequestsPerChild:
    该参数控制 Web 服务器进程在重新启动之前所服务的最大请求数。该参数在缺乏处理 Web 服务器进程的内存的平台(如 Solaris)上非常有用。
  • ThreadsPerChild:
    该参数控制由 Web 服务器处理的当前请求的最大数量。一旦到达限定数量,服务器就会拒绝新到的请求,因此,该参数限制了系统的可伸缩性。

 

Web 容器

  • Thread pool size:
    该参数控制 Web 容器中的线程数。线程数越多,就允许 Web 容器为 Web 服务器中的更多当前请求提供服务,从而提高系统的性能。但该参数也增加了 CPU 的使用,因此,它限制了系统的可伸缩性。
  • Connection backlog:
    在完全利用某一线程池时,会有更多针对 Web 容器的当前请求在排队。该参数控制允许排队请求 Web 容器的最大请求数。

    所以,thread pool size 和 connection backlog 一起确定了能够让 Web 容器为其提供服务的当前请求的最大请求数(例如,如果将 thread pool size 设置为 50,将 connection backlog 设置为 500,那么 Web 容器只能为 550 个当前请求提供服务)。确保让 Web 服务器提供服务的最大当前请求数决不超过 Web 容器(群集环境中的 Web 容器集)可以为其提供服务的最大当前请求数,这一点非常重要。

 

数据源/连接池

  • Min/Max size
    该参数控制连接池中最大 JDBC 连接数和最小 JCBC 连接数。为了避免创建/毁坏连接池中连接所带来的开销,可以为这两个参数设置相同的值。连接池中的连接数越大,中层(mid-tier)和后端服务器消耗的资源(内存,网络 I/O等)也就越多,连接池中连接数较少,可以增加请求的响应时间。因此,应该优化连接池,以便在系统上获得预期的工作量。根据经验,每 10 个用户允许有一个连接。
  • Statement Cache size
    该参数控制由连接池缓存的最大预编译语句数。

 

JVM 垃圾收集对性能和可伸缩性的影响
垃圾收集(GC)通过删除堆中其他任何对象不再引用的对象来回收一部分堆。JVM 中的所有线程都被挂起,直到完成 GC(在热点 JVM 中进行较小的 GC 时,存在例外)。因为在执行 GC 期间,系统中的所有活动都被阻塞,所以 GC 又被称为“stop-the-world”场景。因此,GC 的频率和持续时间对 J2EE 的性能和可伸缩性都会产生极大的影响。

GC 的频率和持续时间取决于三个因素:

  • Java 堆的大小
    堆越小,GC 就越频繁;另一方面,堆越大,GC 持续的时间也就越长。
  • 短生存期对象数
    如果应用程序创建了太多的短生存期对象,那么就会经常发生 GC。
  • 垃圾收集算法
    GC 算法是供应商特定的。关于 IBM 的 JVM 及其 GC 算法的更多信息,可以从 JVM Diagnostics Guide中获得。关于 Sun 的热点 JVM 及其算法的信息,可以从 Tuning Garbage Collection 中获得。

 

对用于 IBM JVM 的“verbosegc”的解释
IBM 的 JVM 1.3.1 使用“标记-清除”垃圾收集(即 GC)算法。GC 有三个阶段:标记、清除和可选地整理。在标记阶段,将所有“活的”对象添加到标记向量。在清除阶段,识别所有已经分配但不再被引用的对象。当已经从堆中删除垃圾时,GC 可以考虑整理由此产生的对象集,以删除它们之间的空间。因为整理花费的时间可能很长,所以可能的话,GC 会试图避免整理,实际上,整理也是很少发生的事件。


            <AF [5 ]:Allocation Failure.need
            32 bytes,
            286 ms since last AF>
            <AF [5 ]:managing allocation failure,action=1 (0/6172496)(247968/248496)>
            <GC(6):GC cycle started Tue Mar 19 08:24:46 2002
            <GC(6):freed
            1770544 bytes,
            31%free (2018512/
            6420992),in 25 ms>
            <GC(6):mark:23 ms,sweep:2 ms,compact:0 ms>
            <GC(6):refs:soft 1 (age >=4),weak 0,final 0,phantom 0>
            <AF [5 ]:completed in 26 ms>
            

以上是 IBM JVM 的一个样例 GC 输出。标签中的第一行显示,该线程需要 32 个字节,而且,自上次内存分配失败以来(即自上次发生 GC 以来),已经有 286 毫秒的时间。当堆达到最大大小,无法再分配内存时,就会发生内存分配失败。出现分配失败之后就会开始 GC 并释放内存。标签中的第四行显示,当前堆的大小大约为 6 MB;在这个 GC 周期中,大约释放了1.7 MB 的内存,目前,有 31% 的堆是空闲的。标签中的最后一行显示,完成该 GC 周期用了 26 毫秒的时间。

对用于 SUN JVM 的“verbosegc”的解释
SUN 的 JVM 1.3.1 使用分代垃圾收集算法。该算法假定应用程序中的大多数对象都死得很“年轻”。所以,使用分代的方法管理内存:内存池中保存着不同年代的对象。垃圾收集发生在每一代填充满的时候;对象是在 Eden中分配的,因为早期损坏率的缘故,大部分对象“死”在这个时期。当 Eden 填充满时,会发生较小的垃圾收集,在这期间,存活下来的一些对象被转移到较老的一代。当需要对较老的一代进行垃圾收集时,会有一次较大的收集,因为涉及到所有存活对象,所以这次收集通常比较慢。对象存活得越长,它经历的收集就越多,GC 也就变得越慢。通过安排大多数对象的存活期不超过一个收集周期,垃圾收集可以变得非常有效。


            [GC 325407K->83000K(776768K), 0.2300771 secs]
            [GC 325816K->83372K(776768K), 0.2454258 secs]
            [Full GC 267628K->83769K(776768K), 1.8479984 secs]
            

上述代码的前两行显示了较小的 GC。每个 GC 大约用去 230 毫秒的时间,释放了大约 0.7 MB 的内存。第三行显示了一个完全(Full)或较大(Major)GC。它花费了1.8 秒的时间,释放了大约 0.7 MB 的内存。以上代码显示,较大 GC 非常昂贵,所以应该尽可能地避免。

我们的实验显示,对于大小超过 512 MB 的堆,多数 GC 花费的时间都会超过 5 秒,并且会使系统不稳定。所以我们得出结论,在 SUN 平台上,堆大小超过 512 MB 会导致性能下降。有关 JVM 性能调优参数的更多信息,可以从 eClient Tuning 指南中获得。

了解性能目标
性能目标可以分成三大主要种类:

  • 响应时间目标
    目标是单个操作的“可接受”响应时间的集合。例如,对于单个参数搜索,100 次找到目标所花费的响应时间应该是 <= 1 sec。
  • 吞吐量目标
    已知一组操作的“可接受”响应时间,确定系统可以达到的最大事务吞吐量。例如,对于特殊装置,可以设置 25000 次查看/小时的实现目标。
  • 可伸缩性目标
    已知最大事务吞吐量,确定系统可以为多少当前用户提供服务。例如,在吞吐量是 25000 次查看/小时的情况下,可以将目标设置为一个系统上 400 名当前用户。

针对单用户响应时间问题的调试方法
各种组件中的性能日志可以很容易将性能问题与单用户响应时间问题隔离开来。您需要在“PERF”模式下收集 eClient(或者您的自定义应用程序)、DB2 Content Manager API、LS 和 RM 日志。如果需要的话,还要确定在哪儿花费了时间并进行代码路径分析。重要的是,要确保时间没有花费在网络上,对于查看和猎取大型文档尤其如此。

以下是一个场景,在该场景中,TCP 堆栈调优改进了查看操作的响应时间。我们假定,eClient 追踪日志指出 loadDoc() 花费了 3 秒的时间。DB2 Content Manager API 日志 dklog.log 显示,调用 RM 检索文档花费了 2.9 秒的时间。而 RM 展示,处理检索文档的请求只花费了 0.2 秒的时间。我们可以很容易地得出这样的结论:大部分时间都花费在将数据从 RM 服务器传输到中层服务器上。当 Windows® 中层服务器与 AIX®/SUN 后端服务器进行通信时尤为如此,所以您应该调整中层和 RM 机器上的 TCP 堆栈。

吞吐量问题的调试方法
吞吐量问题通常是由处理请求期间因为争用资源(CPU、内存、硬盘、线程池、连接池等)而导致的等待时间增加所引起的。例如,如果将 Web 容器中的线程池大小设置为 50,那么该容器只能处理 50 个当前请求。第 51 个请求必须排队,直到 50 个请求中完成一个为止。因此,要获得最大可能的吞吐量,就必须尽快调整队列中的所有组件/资源,以减少(在许多情况下,是消除)等待时间。WebSphere® 资源分析器 (Tivoli® Performance Analyzer in WebSphere 5.x)是一个极好的工具,可以用它来监视关键资源(Thread Pool、Connection Pool、JVM、Web Container 等),识别 J2EE 环境中的瓶颈。

探测线程池可以知道活动线程的平均数、已创建/毁坏线程的数量、请求的平均等待时间等。活动线程的平均数是到达容器的当前请求数的标准。如果活动线程的平均数时常接近线程池的最大大小,这说明该线程池太小,不足以满足工作量。只有在 CPU 没有完全利用的情况下,才考虑增加池的大小。如果活动线程的数量上下波动很大,或者远远低于期望工作量,那么请求无法以有序的方式到达 Web 容器。这可能是因为网络拥挤,需要在路由器/开关处排队等待,或者是因为 Web 服务器插件没有将请求转发给 Web 容器。

探测 Web 容器可以知道 jsp/servlet 的平均响应时间、请求 jsp/servlet 的当前请求数。如果 jsp/servlet 的响应时间随当前请求的数量而增加,那么显然它可以清楚指示资源的争用情况。进行代码路径分析,以查看阻塞请求并发执行的代码中是否存在同步阻塞。在某些情况下,转储线程对于要查看到底是在哪个方法上发生了阻塞是非常有用的。随 WebSphere 提供的 DrAdmin 工具可以用来进行转储操作(使用以下命令, DrAdmin -serverPort <serverPort> -dumpThreads' )。

探测连接池可以知道已创建连接的数量、已毁坏连接的数量、从连接池中取出连接的数量和返回连接池中的连接数等。观察连接的平均等待时间和连接池的利用百分率,以查看这些线程是否在等待从池中获得连接。如果是这种情况,则应该增加连接池的大小。同时,观察已创建和已毁坏连接的平均数。如果有太多的连接正被毁坏和重建,那么应该增加闲置超时时间。

探测 JVM 可以知道用去的总内存、空闲内存的百分率、使用内存的百分率等。可以观察空闲内存的百分率来识别内存漏洞。内存漏洞会导致频繁的 GC,而且会导致高 CPU 使用率和低吞吐量。

如果探测以上资源都无法识别瓶颈(即资源争用),那么请观察系统资源(比如 I/O、磁盘 I/O、分页等)。最后,监视随工作量增加时的 CPU 使用率。CPU 使用率应该随工作量的增加呈线性增长。如果 CPU 在达到吞吐量目标之前达到最大使用率,那么应该试着减小线程池的大小。如果 CPU 使用率下降,响应时间仍在“可接受”范围内,那么我们无法达到目标。如果无法调整系统,这意味着我们将冲击系统能够达到的最大吞吐量。如果 CPU 的利用没有达到最大值,但形成了峰值,那么可以采用 GC 行为。如果 GC 周期对应于 CPU 峰值,垃圾收集会使用太多的 CPU。应用 JVM 技术可以减少 GC 的频率和持续时间。

可伸缩性问题的性能调试技术
以下是一个问题描述:10 名用户在“无须考虑时间”的情况下可以达到吞吐量目标,但 400 名用户在“切实考虑时间”的情况下却无法达到相同的吞吐量。这类问题主要是因为许多用户越来越多地争用资源引起的(比如,随着用户数量的增加,共享内存的使用在增加)。可以使用上面描述的所有技术来识别瓶颈。在本例中,随着用户数量的增加,要注意资源的利用情况。

结束语
要对 J2EE 应用程序进行性能调优和调试,要求不但要深入了解 J2EE 体系结构,还要深入了解 Web 服务器的体系结构,以及 JVM 和操作系统的内存分配模型,以便调配资源。我们首先讨论了如何通过各种模块处理 J2EE 应用程序的 HTTP 请求,以队列和参数的形式协调队列中的每一个模块,本文通过这些讨论为性能调优和调试建立了必要的基础。接下来,我们讨论了 Sun 和 IBM JVM 的垃圾收集算法,以及它们对应用程序的性能和可伸缩性的影响。最后,我们将 J2EE 应用程序的典型性能问题和可伸缩性问题分成三类进行说明,并描述了一个系统的调试方法。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有