【发布时间】:2017-11-16 06:25:17
【问题描述】:
我们最近将银行应用程序从 java 1.6 升级到 1.8,将 jboss 4.x 升级到 wildfly 10.1。
我们观察到 java 消耗了机器上所有可用的内核 (10)。
谁能告诉我这是什么原因,通常jboss 4.x的最大CPU利用率是4核。
我需要为垃圾收集配置什么吗?
下面是(添加在消耗高cpu的进程上)的结果
ps -eLo pid,lwp,nlwp,ruser,pcpu,stime,etime,args|grep 3630
下面是每个 LWP 消耗高 cpu 的十六进制
现在我检查了线程转储 对于 LWP 7914
"default task-7" #182 prio=5 os_prio=0 tid=0x00007f5c24033800 nid=0x1c1a 可运行 [0x00007f5bb85e5000] java.lang.Thread.State: 可运行于 org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:150) 在 io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:240) 在 io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:2028) 在 io.undertow.servlet.spec.ServletOutputStreamImpl.writeBufferBlocking(ServletOutputStreamImpl.java:563) 在 io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:216) 在 java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) 在 java.io.BufferedOutputStream.write(BufferedOutputStream.java:95) - 在 com.eko.app.offlineKyc.servlet.KycPictureServlet.doGet(KycPictureServlet.java:58) 锁定 (a java.io.BufferedOutputStream) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 在 io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) 在 com.eko.framework.CrossScriptingFilter.doFilter(CrossScriptingFilter.java:48) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 com.eko.framework.URLSessionFilter.doFilter(URLSessionFilter.java:38) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 org.mifos.framework.security.util.FileNameFilter.doFilter(FileNameFilter.java:59) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) 在 io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) 在 io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) 在 org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) 在 io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53) 在 io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) 在 io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) 在 io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59) 在 io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) 在 io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) 在 io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) 在 io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) 在 io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) 在 io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) 在 io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) 在 io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745)
适用于 LWP 7249
"default task-27" #231 prio=5 os_prio=0 tid=0x00007f5c2401c000 nid=0x1c51 可运行 [0x00007f5ca9a63000] java.lang.Thread.State: 可运行于 org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:158) 在 io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:179) 在 io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:1993) 在 org.xnio.channels.Channels.writeBlocking(Channels.java:152) 在 io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:283) 在 io.undertow.io.BlockingSenderImpl.writeBuffer(BlockingSenderImpl.java:190) 在 io.undertow.io.BlockingSenderImpl.send(BlockingSenderImpl.java:71) 在 io.undertow.server.handlers.resource.CachedResource.serve(CachedResource.java:187) 在 io.undertow.servlet.handlers.DefaultServlet.serveFileBlocking(DefaultServlet.java:332) 在 io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:180) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 在 io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) 在 com.eko.framework.MifosNGFilter.doNormal(MifosNGFilter.java:283) 在 com.eko.framework.MifosNGFilter.doFilter(MifosNGFilter.java:137) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 com.eko.framework.CrossScriptingFilter.doFilter(CrossScriptingFilter.java:48) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 com.eko.framework.URLSessionFilter.doFilter(URLSessionFilter.java:38) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 org.mifos.framework.security.util.FileNameFilter.doFilter(FileNameFilter.java:59) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) 在 io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) 在 io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) 在 org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) 在 io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53) 在 io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) 在 io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) 在 io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59) 在 io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) 在 io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) 在 io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) 在 io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) 在 io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) 在 io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) 在 io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) 在 io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) 在 io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745)
下面是完整线程转储的链接 Thread dump
服务器不稳定,所以我们不得不恢复到 jdk 1.6 和 jboss 4。我想知道 jboss 4 一切正常,现在我无法确定问题出在哪里,通过 Wildfly 设置或我的应用程序或GC 设置。
线程转储分析的链接 Thread dump analysis result
代码KycPictureServlet
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream out = null;
FileInputStream fin = null;
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
try {
String filename = String.valueOf(request.getParameter("fileName"));
String folderPathId = String.valueOf(request.getParameter("folderPathId"));
String kycDocPath = "";
System.out.println("Folder Path : " + folderPathId + " \t" + filename);
if (folderPathId != null && !folderPathId.equals("null")) {
kycDocPath = new StoragePathService().getStoragePathByPathID(Integer.parseInt(folderPathId)).getFolderPath();
} else {
kycDocPath = new StoragePathService().getStoragePathByPathID(EkoDBConstants.KYC_FILE_UPLOAD_PATH).getFolderPath();
}
String uploadFolderPath = kycDocPath;
final String filetofetch = uploadFolderPath + filename;
if (filetofetch.toLowerCase().endsWith("pdf")) {
response.setContentType("application/pdf");
// response.setHeader("Content-Disposition", "inline;
// filename=\"" + filetofetch + "\"");
} else if (filetofetch.toLowerCase().endsWith("tif") || filetofetch.endsWith("tiff")) {
response.setContentType("image/tiff");
} else {
response.setContentType("image/jpeg");
}
File uploadFolder = new File(filetofetch);
if(uploadFolder != null && uploadFolder.exists()){
out = response.getOutputStream();
fin = new FileInputStream(filetofetch);
bin = new BufferedInputStream(fin);
bout = new BufferedOutputStream(out);
int ch = 0;
;
while ((ch = bin.read()) != -1) {
bout.write(ch);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bin != null) {
bin.close();
}
if (fin != null) {
fin.close();
}
if (bout != null) {
bout.close();
}
if (out != null) {
out.close();
}
}
}
以前没有任何 finally 块,所以在异常流没有被关闭的情况下,第二件事我添加了额外的检查来检查文件是否存在然后只打开流。
进行更改后,不再有线程卡在该 servlet 上。
我已经采取了最新的转储,发现一些奇怪的进程消耗 cpu 并且没有结束
"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007ff8dc231000 nid=0x11b6 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007ff8dc22e800 nid=0x11b5 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007ff8dc22d000 nid=0x11b4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007ff8dc22a000 nid=0x11b3 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
我还配置了从 OLD Jboss 4 复制的 GC 设置
在线程转储中我发现一些 LWP 正在消耗 CPU 并且没有结束
"VM Thread" os_prio=0 tid=0x00007ff8dc1e9000 nid=0x11B411af runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007ff8dc01e800 nid=0x11a6 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007ff8dc020800 nid=0x11a7 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007ff8dc022000 nid=0x11a8 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007ff8dc024000 nid=0x11a9 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007ff8dc026000 nid=0x11aa runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007ff8dc027800 nid=0x11ab runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007ff8dc029800 nid=0x11ac runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007ff8dc02b800 nid=0x11ad runnable
"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x00007ff8dc02d000 nid=0x11ae runnable
内存和GC设置
JAVA_OPTS="-Xms4G -Xmx12G -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi.dgc.server.gcInterval=1800000 -XX:-UseConcMarkSweepGC -XX:SurvivorRatio=6 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/data/eko/GC.log -verbose:gc -XX:NewRatio=2"
【问题讨论】:
-
好吧,那么您的
com.eko.app.offlineKyc.servlet.KycPictureServlet.doGet是做什么的?基于线程转储,考虑到它是一个 servlet,它运行了很长时间。您确定您正确关闭了所有资源(流、servlet 响应、..)吗?第一个线程是处理一些 HTTP 请求的 servlet 处理程序,显然阻塞了 IO,在写入时消耗 CPU。堆栈给出了准确的行号:58卡在哪里 - 去检查一下。第二个是 servlet 过滤器,可能与第一个有关。 -
是的,你是对的,它是一个 servlet,如果我们之间有任何异常,我们不会关闭流,所以我添加了 finally 块来处理这种情况。将部署更改并分享结果。
-
@yntelectual 在部署更改后,现在不会遇到该 servlet 的问题。我再次分析了线程转储并发现了一些奇怪的结果并添加了相同的结果。如果您能就 GC 设置提出建议,那就太好了。
-
没有简单的答案。问题何时显现?在重负载下还是不使用?它只是在一段时间后发生吗? GC线程真的会消耗你所有的CPU吗?如果 GC 线程确实消耗了过多的 CPU,那么您可能有一些内存泄漏并且服务器正拼命地试图保持在其堆限制内。创建一个MRE 并将其用于分析。尝试将 Xmx 值降低到 2g 之类的值,重现问题并进行堆转储。分析它并调查您是否没有任何泄漏。
标签: java jboss wildfly wildfly-10 application-server