首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 IBM Support Assistant 找出在企业应用程序中确定和解决性能问题的模式(2)

使用 IBM Support Assistant 找出在企业应用程序中确定和解决性能问题的模式(2)

案例研究 2:高系统 CPU 使用我们的第二个案例研究来自生产环境的电信应用程序(以下简称为 TelecomApp)。该应用程序被用作向数百万手机用户提供服务的首页。用户可以点击并获取各种多媒体内容,如铃声、壁纸、比分直播等。在生产环境中,该应用程序的主要组件包括一个 Web 门户节点的集群,该节点连接到后端内容管理系统节点的一个集群,后一个节点又转而从在一台大型多核计算机上运行的数据库中获取他们的数据。
报告的问题是,在用户量为低到中等时出现非常高的 CPU 利用率。我们使用  收集了详细的系统日志。快速浏览 CPU 日志,可以发现 webportal 节点的系统 CPU 水平很高(参见图 6)。
图 6. 在修复代码前,nmon 的 Web 门户节点 CPU 图通过 WebSphere Application Server 管理控制台启用的详细 GC 日志记录,我们使用 GCMV 分析了详细的 GC 日志收集(默认情况下,它们保存在 WebSphere Application Server 中的 native_stderr.log)。GC 日志看起来没问题,但排队等待终结的对象数量非常高,这种对象数量接近 40,000 个(参见图 7 中的虚线)。还记得,包含一个 finalize() 方法,并且被垃圾收集器认为是无法访问(废弃)的所有这些对象,都被推送到一个终结队列。过一些时间之后,终结器线程将使该对象离开终结队列,并调用它的 finalize() 方法。排队等待终结的对象过多,可能会导致两种类型的性能退化:
  • 高 CPU 使用率,原因是终结器线程的工作,或
  • 高内存利用率,原因是那些废弃的但仍可以从尚未终结的对象访问的所有对象都不能被回收。
图 7. GCMV: 排队等待终结的对象(虚线=原始代码,实线=修复后的代码)图 8. MAT: 在终结器引用统计中,终结器所引用的对象的直方图我们在 WebSphere Application Server 启用了堆转储设置,并在分阶段环境中提取一个堆转储,以找出被终结的对象类型。我们使用 MAT 来分析堆转储,在终结器引用统计中查看终结器引用的对象的直方图(参见图 9)。在排队等待终结的 38,469 个对象中,有 35,626 个属于 java.util.zip.ZipFile 类型。我们提取线程转储,并使用 IBM Thread and Monitor Dump Analyzer(也随 IBM Support Assistant 提供)分析它们,这会使我们注意到负责创建这些类型为 java.util.zip.ZipFile 的对象的代码(参见图 10)。
图 9. IBM Thread and Monitor Dump Analyzer: 负责创建 java.util.zip.ZipFile 的代码该代码在类加载器上调用 getResource(Filename) 方法,从而处理特定属性文件的确切路径。从本质上讲,该方法在类路径中一个接一个地解压所有 JAR 文件,从而搜索给定的文件名。这会导致创建很多 java.util.zip.ZipFile 对象(每一个对象都有一个终结方法)和大量的磁盘读取活动。JAR 文件的解压和相关的磁盘读取活动,是所观察到的大系统 CPU 背后的原因。此代码通过几种方法被重复,并且都位于各种客户端请求的关键路径上。检测这个问题的根源所采取的步骤如图 10 所示。
图 10. 关联各种工具的输出,以解决 TelecomApp 高系统 CPU 的问题通过将在类路径中搜索该 JAR 文件的代码替换为在给定文件的准确的文件位置,我们修复了这个问题。系统 CPU 占用率马上就下降了(参见图 11)。排队等待终结的对象数量也下降了(参见图 7 中的实线)。请注意,在这两种情况下,在等待终结的对象队列中都有初始高峰;这是因为在启动时要从各种 JAR 中加载所有类。
本案例研究强调了高系统 CPU 使用的场景,问题的发生是由于使用了错误的代码。该案例研究还强调如何关联不同工具的输出,从而了解性能问题的根源。
图 11. 修复代码后,nmon 的 Web 门户节点 CPU 图
返回列表