http://tekkamanninja.blog.chinaunix.net/uid-17176286-id-5180127.html
https://blog.csdn.net/z69183787/article/details/13288039
粘滞线程问题及简单解决
测试代码出现类似如下问题
####<Mar 25, 2017 9:33:09 AM CST> <Error> <WebLogicServer> <PSFPWEB01> <psfp_in> <[ACTIVE] ExecuteThread: '94' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1490405589083> <BEA-000337> <[STUCK] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "626" seconds working on the request "weblogic.servlet.internal.ServletRequestImpl@5c1546e8[ POST /psfp-issued/resource/com.defonds .core.psfp.issued.biz.issued.resource.BatchIssuedResource/issued HTTP/1.1 Content-Type: application/json User-Agent: Java1.6.0_33 Accept: text/html, image/gif, image/jpeg, */*; q=.2 Connection: Keep-Alive Content-Length: 472401 ]", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace: Thread-412 "[STUCK] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)'" <alive, in native, suspended, priority=1, DAEMON> {
,"weblogic.kernel.Default"是从客户端提交请求后产生的线程所在的队列名。这个队列的线程数默认是15个。如果超过15个线程堵塞,则部署的应用将不能访问。同时后台报:
<2008-2-27 下午09时37分48秒 CST> <Error> <WebLogicServer> <BEA-000337> <ExecuteThread: '14' for queue: 'weblogic.kernel.Default' has been busy for "1,720" seconds working on the request "Http Request: /myapp/test/index.jsp", which is more than the configured time (StuckThreadMaxTime) of "600" seconds.>
2,线程数(Tread Count):指派到weblogic.kernel.Default队列的线程数。如果你不需要使用超过15个线程(默认),就不必更改这个属性值。
如果发送该请求较多,很有可能会导致weblogic的线程阻塞,严重会引起weblogic挂起现象。
可以通过以下几种方法解决:
1)修改StuckThreadMaxTime参数,将默认的600s改成1200s,或者其它适合的值。
2)增大线程数,防止线程阻塞问题。
3)优化程序,减少处理时间。
1) 如何修改StuckThreadMaxTime参数值:http://lujinan858.iteye.com/blog/986237
启动weblogic服务,进入控制台:
your_domain->Environment->Servers->your_server->Configuration->Tuning->Stuck Thread Max Time
如下图:
2)怎样增大线程数
window环境下修改【bea】\user_projects\domains\my_domain\bin\setDomainEnv.cmd文件,查询最下面set JAVA_OPTIONS=%JAVA_OPTIONS%
改为:
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.threadpool.MinPoolSize=50
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.threadpool.MaxPoolSize=300
但是本地自测的话肯定就不是第一个问题了,而且如果一个线程600秒都没跑完,再改时间是没用的估计
后来找了一下原因,是因为在数据库修改数据没有提交。而应用页面操作同时对修改数据的表进行修改操作导致锁死不能动,因此出现粘滞线程。
WebLogic是怎样判断粘滞线程(Stuck Thread)和独占线程(Hogging Thread)的
粘滞线程(Stuck Thread),相对比较容易理解,就是那些执行时间超过“粘滞线程最长时间”(默认是600秒)的线程。联机文档是这样说的:
如果执行线程处理某个请求的粘滞时间超过了配置的粘滞线程最大时间,则为“真”。 |
True if the execute thread is stuck working on a request for more than the configured stuck thread maximum time. |
可以通过控制台的设置来增大或减小这个值(虽然绝大部分情况下修改这个值没有什么意义):
控制台 >> 环境 >> 服务器 >> MedRecSvr1 >> 配置 >> 优化 >> 粘滞线程最长时间
WebLogic把某些线程标记为Stuck Thread,是为了提醒我们那些线程执行的时间太长了。我们应该去分析线程为什么需要那么长时间才能执行完(甚至永远执行不完)。不去做根本原因的分析,而单纯的依靠增加“粘滞线程最长时间”这个值的设置来减少Stuck Thread线程的出现,是掩耳盗铃的做法。
独占线程(Hogging Thread),很多资料上都没有讲清楚。先来看看联机文档是怎么说的:
【独占】
如果根据调度程序的自动观察,某个请求独占执行线程的时间超过了正常执行时间,则为“真”。 |
True if the execute thread is being hogged by a request for much more than the normal execution time, as automatically observed by the scheduler. |
【独占线程计数】
请求现在所保留的线程。这些线程将在配置的超时过后被声明为粘滞或在超时结束前返回给池。自优化机制将在必要时进行回填。 |
The threads that are being held by a request right now. These threads will either be declared as stuck after the configured timeout or will return to the pool before that. The self-tuning mechanism will backfill if necessary. |
通过联机文档的解释可以看出,WebLogic要把一个线程标记为Hogging Thread需要满足两个条件:
(1)线程执行时间超过了“正常执行时间”。
(2)线程执行时间还没有超过“粘滞线程最长时间”。
随着时间的推移,Hogging Thread会出现两种不同的状态变化:
(1)在超过“粘滞线程最长时间”之前,请求执行完毕,Hogging Thread被释放,重新回到线程池,等待下一个请求的到来。
(2)超过“粘滞线程最长时间”之后请求还没有执行完毕,Hogging Thread被标记为Stuck Thread,直到最后执行完毕(虽然有可能永远执行不完)。
那么,问题就来了,什么叫做“正常执行时间”呢?它的工作原理是这样:
WebLogic实例在启动时候会同时启动一个计时器,这个计时器每两秒钟扫描一次所有线程,然后根据公式来判断是不是要把某个线程标记为Hogging Thread。
(1)对于那些在刚刚过去的两秒钟内执行完毕的线程,计算出它们的平均完成时间。假设有2个线程执行完了,Thread_A花了1秒,Thread_B花了5秒,那么平均时间Average_Time=(1+5)/2=3
(2)如果7*Average_Time大于4,那么把Hog_Duration设置为7*Average_Time,否则把Hog_Duration设置为4。这个Hog_Duration就是联机文档里面提到的“正常执行时间”。在我们的例子中 7*3=21 > 4 所以Hog_Duration设置为21
(3)逐个扫描其它正在执行的线程,如果某个线程的执行时间已经超过了21秒(Hog_Duration),那么就把该线程标记为Hogging Thread
友情提示,每个不同版本的WebLogic内部的运算机制可能并非是严格按照上面的公式和数值来判断的,这个例子只是为了讲解它的原理。