现场报有一个节点CPU太高,其实这种问题我觉得很好找,之前也介绍过:
1.top找到最消耗CPU的进程
2.top -H -p 线程id显示具体线程占用CPU的情况
-H 指定这个可以显示每个线程的情况,否则就是进程的总的状态
-p 指定需要监控的进程id
3.jstack -l 进程id(weblogic的pid)
4.jstack的结果中:nid指的是top命令查看的线程pid对应,不过一个是10进制,一个是16进制。tidjvm内部线程的唯一标识(通过java.lang.Thread.getId()获取,通常用自增方式实现。)
但本次的问题跟之前的完全不一样,消耗CPU的都是这样的线程,weblogic总共有403个线程,其中waitForRequest有344个:
"[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=6 tid=0x000000000b829800 nid=0x1f5c in Object.wait() [0x000000000e12f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000fbd7bbe0> (a weblogic.work.ExecuteThread)
at java.lang.Object.wait(Object.java:503)
at weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:238)
- locked <0x00000000fbd7bbe0> (a weblogic.work.ExecuteThread)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:264)
这些线程到底是什么呢?之前的blog我说过,这些是处理请求的线程,但还是没有概念,使用Jmeter做一个实验:
先做一个jsp页面,就是睡2秒钟。
<html>
<body>
</body>
<script language="javascript">
<%!
public class DeadLockTest extends Thread {
public void tt(){
try{
Thread.sleep(2000);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
%>
<% DeadLockTest dlt = new DeadLockTest();
dlt.tt();
%>
</script>
</html>
1.weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:238)这种线程在weblogic启动后启动了4个。
2.在压测过程中发现waitForRequest变少,这种处理的线程变多。
"[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=6 tid=0x000000000a7b7000 nid=0x150c waiting on condition [0x00000000101fe000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at jsp_servlet.__login$DeadLockTest.tt(__login.java:69)
at jsp_servlet.__login._jspService(__login.java:103)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
3.压测完之后,发现weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:238)变成了34个。
我认为的结论是:其实这种weblogic.work.ExecuteThread.waitForRequest线程是weblogic处理请求的线程,当它们没有处理现场的时候就是waitForReuest,处于空闲状态,当它们处理请求的时候,堆栈就变化了。目前我面临的这种问题,是之前weblogic有很多的消耗资源的请求,导致weblogic创建了很多这种处理线程。
如何解决这种问题了:首先看access.log里面,找到消耗资源的请求,后者听听用户的声音,哪些功能慢了,结合access.log的请求。毕竟weblogic不像Oracle那样保存了历史处理的信息。