zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

国内首位中间件Oracle ACE:WebLogic执行线程耗尽解决方案

2023-09-11 14:16:00 时间

王超,国内第一位中间件ORACLE ACE,东方宏达中间件技术总监,原ORACLE|BEA 资深中间件现场支持工程师,14年现场支持工作经验,WebLogic 6.1/7.0/8.1/9.2/10.3/11g/12c、Tuxedo技术认证专家。深厚的中间件架构规划、性能调优、问题解决经验,常年为为电信、金融等领域客户提供现场技术支持。


1WebLogic执行线程耗尽


1.1、概述 


WebLogic服务器执行线程耗尽后就不再响应后续请求,WebLogic即出现挂起现象。


WebLogic线程耗尽产生的原因有多种,一般而言线程耗尽是由于线程在争夺某种资源。当一种资源处于缺少状态,比如数据库JDBC连接池的达到最大连接数,就会导致后续的业务线程都卡在等待获取JDBC的连接上,最终导致服务器无法响应后续的服务请求。


1.2、常见线程耗尽原因 


WebLogic服务器线程耗尽,最常见的几种原因如下:



应用程序同步调用。比如业务线程A执行的过程中锁定了资源1,而由于同步调用的原因导致其他业务线程不得不一直无限等待资源1的锁被释放。


业务系统没有使用WebLogic线程池,而使用自定义的线程池。当自定义线程池全部被占用,就会导致没有线程可用于新工作。


1.4、收集信息 


当服务器挂起时,首先使用 java weblogic.Admin t3://server:port PING 来 ping 该服务器。如果服务器能够响应此 ping,则可能是应用程序所使用的线程池耗尽而不是服务器自身。


WebLogic Server 在8.1版本之前使用“Default”线程池响应客户端服务请求,在9.0版本以后使用Default (self-tuning)线程池响应客户端服务请求。这些是在发生线程耗尽时应当检查的线程池。通常情况下,用收集JVM的Thread Dump的办法来分析线程池运行信息。


Linux / Unix系统

任何WebLogic版本均可使用 kill -3 创建诊断问题所需的 Thread Dump。确保在每个服务器上执行几次,每次间隔大约 3 到 5秒,以帮助诊断死锁问题。


在WebLogic 9.2版本或者是更高的版本中,可以直接通过使用JDK的jstack命令来收集Thread Dump信息。


Windows操作系统

任何WebLogic版本均可使用 - 来创建诊断问题所需的 Thread Dump。确保在每个服务器上执行几次,每次间隔大约 3 到 5 秒,以帮助诊断死锁问题。


在WebLogic 9.2版本或者是更高的版本中,可以直接通过使用JDK的jstack命令来收集Thread Dump信息。


1.5、实施步骤 



1.6、分析Thread Dump 


WebLogic除了包含业务系统所使用的执行线程池以外,还包括ListenThread线程池、Socket Reader线程池以及自定义线程池等等。由于WebLogic软件是非常复杂的企业软件,所以在分析的时候,我们不但需要关注业务执行线程池,同时也需要关注其他线程池。WebLogic线程池简易图示如下:


20160816100808222.jpg

Thread Dump线程转储是将当前JVM包含的所有的线程的运行状态的一个映像,包含了:




分析WebLogic服务器线程耗尽的最有用的办法是分析一系列 的Thread Dump。一系列 Thread Dump(一般每隔3 到 5 秒进行三个或更多 Thread Dump)可以帮助分析每个线程从一个 Thread Dump 到另一个 Thread Dump 过程中的状态变化或所缺少的变化。WebLogic服务器线程耗尽导致服务器挂起后,服务器的 Thread Dump 一般显示线程状态从第一个 Thread Dump 到最后一个 Thread Dump 中变化很小。


在 Thread Dump 中查看的内容


所有请求都通过 ListenThread 进入 WebLogic Server。如果 ListenThread 丢失,就无法接收任何工作,因此也无法完成任何工作。确认在 Thread Dump 中存在 ListenThread。ListenThread 应当在 socketAccept 方法中。下面示例说明监听线程 (Listen Thread) 的形式。


20160816100818931.jpg


Socket Reader 线程接受来自监听线程队列的传入请求,并将该请求放入执行线程队列。如果 Thread Dump 中没有 Socket Reader 线程,则在某个地方存在导致 Socket Reader 线程消失的错误。应当始终保持至少有三个 Socket Reader 线程。一个 Socket Reader 线程一般用于轮询功能,另外两个用于处理请求。下面是一个 Thread Dump 示例中的 Socket Reader 线程。


20160816100826933.jpg


通常,业务代码使用的是WebLogic默认的执行线程池,在WebLogic 8.1之前以“Default”命名,在9.x以后以“weblogic.kernel.Default(self-tuning)”命名。查看执行线程的状态,主要看thread dump里面的state的值。同时,为了更快的定位问题,WebLogic服务器会将运行时间超过600秒的执行线程标记为“STUCK”状态,如下所示:


20160816100836627.jpg

20160816100845743.jpg

20160816100855898.jpg

20160816100904957.jpg

20160816100912120.jpg

20160816100921301.jpg

20160816100929200.jpg


java中线程的状态


Thread Dump中,Java线程的各种状态如下:



运行状态。表示线程正在java虚拟机中执行,但是可能正在等待操作系统的其他资源,比如CPU


阻塞状态。表示线程正在等待监视器锁。表示线程正在等待获取监视器锁,以便进入同步方法或者同步代码快,也有可能是从wait()方法被唤醒而等待再次进入同步方法或者同步代码块


等待状态。表示当前线程需要等待其他线程执行一些特殊操作,比如当前线程调用了a.wait()方法,它正在等待其他线程调用a.notify或a.notifyAll方法;如果当前线程调用了threada.join(),那么它在等待threada执行完成


收集thread dump的示例脚本如下:

 20160816100941476.jpg

本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2016-08-16