Web 模块或应用程序服务器停止处理请求
如果应用程序服务器进程自发关闭,或者 Web 模块停止对新请求进行响应,那么快速确定导致此停止的原因非常重要。可以使用下列其中一些方法来确定问题是 Web 模块问题还是应用程序服务器环境问题。
如果应用程序服务器进程自发关闭,或在应用程序服务器上运行的 Web 模块停止对新请求进行响应,请完成以下步骤:
- 如果可能,尝试通过在不同服务器上安装 Web 模块来隔离问题。
检查名称类似于 javacore[number].txt 的文件的产品目录结构。此文件是应用程序服务器进程自发关闭时 JVM 创建的 Java™ 线程转储文件。
如果应用程序服务器的进程自发关闭,那么您需要分析 SDUMP。
- 使用 Tivoli® Performance Viewer 确定是否有任何应用程序服务器资源(如 Java 堆或数据库连接)已达到其最大容量。如果存在资源问题,请查看应用程序代码以找出可能的原因:
- 如果要将数据库连接指定给某个请求但在请求完成处理时未释放这些数据库连接,那么确保该应用程序代码对 finally{} 块中的任何打开的 Connection 对象执行 close()。
- 如果使用中的 servlet 引擎线程稳步增加,那么查看应用程序同步代码块以了解可能的死锁情况。
- 如果 JVM 堆大小稳步增加,查看应用程序代码以了解可能的内存泄漏,如静态(类级别)集合导致对象从不进行垃圾回收。
- 在应用程序服务器上启用详细垃圾回收,以帮助您确定是否存在内存泄漏问题。此功能将可用内存数量和使用中的内存数量的详细说明添加到 JVM 错误日志文件。要启用详细垃圾回收:
在管理控制台中,单击 server_name。然后,在“服务器基础结构”部分中,单击 ,然后选择详细垃圾回收。
在管理控制台中,单击 server_name。然后,在“服务器基础结构”部分中,单击 ,然后选择详细垃圾回收。
- 停止并重新启动应用程序服务器。
- 定期浏览日志文件以获得垃圾回收语句。查找以“allocation failure”开头的语句。此字符串表明内存分配需求已触发 JVM 垃圾回收,以释放未使用的内存。分配失败是正常情况,并不一定表明问题。但是,分配失败语句后跟的语句显示需要多少字节以及分配多少字节。如果这些字节需要的语句指示 JVM 保持分配更多内存供自己使用,或者 JVM 无法分配它所需的内存数,那么可能存在内存泄漏。
还可以使用 Tivoli Performance Viewer 来检测内存泄漏问题。
确定应用程序服务器是否内存不足。如果确定应用程序服务器内存不足,那么可能出现下列其中一种情况:
- 在应用程序代码中存在必须解决的内存泄漏问题。要找到内存泄漏的原因,请在管理控制台的“Java 虚拟机”页面上启用 RunHProf 属性。server_name
是问题应用程序服务器的名称。启用 RunHProf 属性后,您必须:
- 将 HProf 参数字段设置为类似于 depth=20,file=heapdmp.txt 的值。此值显示异常堆栈最多为 20 个级别,并将堆转储输出保存到 app_server_root/bin/heapdmp.txt 文件。
- 保存这些设置。
- 停止并重新启动应用程序服务器。
- 如果可能,那么重现该情况,或访问导致应用程序服务器的进程自发停止或其 Web 模块停止对新请求进行响应的资源。然后停止应用程序服务器。如果不能再现该情况或访问该资源,那么等待直到问题再次发生,然后停止应用程序服务器。
- 检查保存堆转储的文件。例如,检查 app_server_root/bin/heapdmp.txt 文件:
- 搜索字符串“SITES BEGIN”。这将查找内存中 Java 对象列表的位置,其显示分配给对象的内存数量。
- 每当有 JVM 内存分配就有 Java 对象列表。有内存实例化的对象类型以及跟踪堆栈标识(转储中它处列出)记录,记录显示进行分配的 Java 方法。
- Java 对象列表是按分配的字节数降序排列的。根据泄漏性质,问题类应该显示在该列表的顶部旁,但不总是这样的情况。在列表中查找大量内存或正在实例化的相同类的频繁实例。对后一种情况,使用跟踪堆栈列中的标识来识别在相同类和方法中重复发生的分配。
- 检查相关跟踪堆栈中表明的源代码以获得内存泄漏的可能性。
- JVM 正在使用允许使用的最大堆大小。在这种情况下,如果您有足够的存储器可用于增大应用程序服务器的最大堆大小设置,那么应增大该设置。
- 服务器运行时发生问题。如果您确定服务器运行时存在问题,那么确保应用了产品的所有服务更新。如果在应用所有服务更新后问题仍然存在,请与 IBM® 技术支持联系。
- 在应用程序代码中存在必须解决的内存泄漏问题。要找到内存泄漏的原因,请在管理控制台的“Java 虚拟机”页面上启用 RunHProf 属性。server_name
是问题应用程序服务器的名称。启用 RunHProf 属性后,您必须:
浏览线程转储以获得线索:
每次应用程序服务器进程自发关闭时,JVM 就创建线程转储。还可以强制应用程序创建线程转储。创建转储后,可以检查该转储以获得有关未处理新请求的原因方面的线索。
要强制线程转储:
- 使用 wsadmin 命令提示符,获取问题应用程序服务器的句柄:
wsadmin>set jvm [$AdminControl completeObjectName type=JVM,process=server_name,*]
其中 server_name 是服务器的名称。
- 生成线程转储:
wsadmin>$AdminControl invoke $jvm dumpThreads
注: dumpThreads 命令将根据 -Xdumps 设置创建其他类型的转储文件。转储输出根据平台不同而有所变化,并且可能会包含系统核心文件、堆和快照转储。 在 profile_root/logs 目录中查找名称类似于 javacore.jobnum.jobuser.jobname.timestamp.txt 的输出文件。
在产品的安装根目录中查找名称类似于 javacore.date.time.id.txt 的输出文件。
在应用程序创建转储后,可以检查以获得下列线索:
文件开头部分中的“error”或“exception information”字符串。这些字符串指示导致应用程序服务器的进程自发关闭的线程。如果您强制转储,那么不会出现这些字符串。
查找多余的当前堆大小。该线程转储显示有关当前 Java 堆大小以及最小和最大堆大小设置的信息。
查找进程中每个线程的快照。线程转储包含进程中每个线程的快照,从标记为“Full thread dump”的部分开始。
- 查找描述中包含“state:R”的线程。这样的线程是活动的并在强制转储或进程退出时运行。
- 在相同的 Java 应用程序代码源位置中查找多个线程。来自相同位置的多个线程可能表明死锁条件(监视器上多个线程在等待)或无限循环,并帮助表明有问题的应用程序代码。
查找进程中每个线程的快照。线程转储包含进程中每个线程的快照,从标记为“Thread Information”的部分开始。
- 查找等待被其他线程挂起的锁定的线程。
- 在相同的 Java 应用程序代码源位置中查找多个线程。来自相同位置的多个线程可能表明死锁条件(监视器上多个线程在等待)或无限循环,并帮助表明有问题的应用程序代码。
产品运行时中的特定组件在同一 Java 代码源位置具有特定类型的线程是很正常的。这些组件包括 Web 容器、EJB 容器和 ORB 线程池。
- 使用 wsadmin 命令提示符,获取问题应用程序服务器的句柄:
IBM 支持机构提供了一些文档和工具,可以帮助您收集在解决问题时所需要的信息,从而为您节省时间。打开问题报告前,请参阅“支持机构”页面: