Tomcat消耗高CPU

15

Tomcat.exe正在消耗75%的CPU。

是否有人知道为什么会发生这种情况,以及如何降低CPU占用率?

我正在使用Tomcat5.5和J2SDK v 1.4.2_12。


当我重新启动Tomcat服务器时,它的CPU利用率保持在10-15%。我开始使用一个名为“A”的应用程序,一旦它被使用了5-6次,CPU利用率就会停留在60-70%,并且永远不会降下来。我需要重新启动服务器。同样的应用程序在其他生产环境中运行良好,但在UAT环境中出现问题。 - Miral
10个回答

11
如果您的CPU使用率高达75%并且不知道原因,我建议您向tomcat进程发出kill -3指令(如果您有控制台,则使用ctrl-break)以获得线程转储(在负载高时!)。 根据我的经验,大多数线程应该是空闲的或处于io-wait状态。 查找在堆栈跟踪中重复出现的任何单个代码分支,并且那就是您可能的罪魁祸首(非io-waits!)。 这是“穷人的性能分析工具”,通常是解决这些问题的最佳和最有效的方法。

如果您想将输出保存在文件中,可以使用jstack命令: jstack <pid> > 文件名。请注意,jstack位于JDF发行版中。 - Frizz1977
感谢 @Frizz1977 :) - solr

5

我的日志里充满了Tomcat的日志。我将它们全部删除后,CPU使用率显著下降。


4

4

Lambda Probe 是一个非常方便的工具,用于监控Tomcat。

你使用的是四核CPU系统吗?可能Tomcat在其中3个核心上运行100%。我首先会测试应用程序中是否存在无限循环或类似问题。


3

首先(适用于所有Java应用程序),您必须确定使用CPU的线程。在JDK 1.6中,这是可能的。通过使用java.lang.management.ManagementFactory.getThreadMXBean()来实现。 以下是示例用法(JSP):

<%@ page import="java.lang.management.*, java.util.*" %>
<%!
    Map cpuTimes = new HashMap();
    Map cpuTimeFetch = new HashMap();
%><%
long cpus = Runtime.getRuntime().availableProcessors();
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
long now = System.currentTimeMillis();
ThreadInfo[] t = threads.dumpAllThreads(false, false);
for (int i = 0; i < t.length; i++) {
    long id = t[i].getThreadId();
    Long idid = new Long(id);
    long current = 0;
    if (cpuTimes.get(idid) != null) {
        long prev = ((Long) cpuTimes.get(idid)).longValue();
        current = threads.getThreadCpuTime(t[i].getThreadId());
        long catchTime = ((Long) cpuTimeFetch.get(idid)).longValue();
        double percent = (current - prev) / ((now - catchTime) * cpus * 10000);
        if (percent > 0 && prev > 0) {
            out.println("<li>" + t[i].getThreadName() + " " + percent + " (" + prev + ", " + current + ")");    
        }
    }
    cpuTimes.put(idid, new Long(current));  
    cpuTimeFetch.put(idid, new Long(now));
}
%>

之后,您可以获取线程转储并分析该线程中的代码以解决CPU使用过多的问题。


3
我们刚刚解决了一个问题,我们的Tomcat实例运行时CPU使用率非常高,每隔几秒钟就会飙升到100%甚至更高,然后又短暂地下降。这种情况一天到晚都在发生,无论服务器是否在执行任何工作。我们正在使用Java 8和Tomcat 8。
我们没有在网上找到解决方案,所以我在这里发布帖子,希望能帮助其他人。
我们在tomcat/conf/Catalina/localhost目录中使用了配置选项,将Tomcat指向了另一个目录,而不是其自己的webapps目录。该目录中的xml文件如下所示:
<?xml version='1.0'?>
<Context
docBase="/opt/dspace/amaddev/dspace-6.3/webapps/jspui"
reloadable="true"
cachingAllowed="false"/>

这样做是有用的,Tomcat将运行这些文件夹中的代码而不是它自己的webapps文件夹。 然而,我们遇到了一个问题,即CPU使用率不断飙升。
为了测试,我们从conf / Catalina / localhost目录中删除了xml文件,并重新启动了Tomcat。 骤然间,我们又拥有了一个正常、表现良好的Tomcat。 为了将Tomcat指向其他目录(我们编译DSpace代码的目录),我们只需要在conf / server.xml中使用Host条目,并将appBase设置更改为我们的DSpace目录:
<Host name="localhost"  appBase="/opt/dspace/amaddev/dspace-6.3/webapps"
        unpackWARs="true" autoDeploy="true">

这样做可以实现我们的目标,而且在服务器空闲时CPU使用率非常低(低于1%)。

2
所有答案都涵盖了如何进行精确诊断,此外,根据我的经验,您的应用程序中可能是无限循环导致问题的罪魁祸首。
正如J-16 SDiZ所说,您最好运行性能分析器来将问题缩小到一个应用程序。

1
在我的情况下,我刚刚安装了默认设置的Tomcat8。我需要设置内存参数-Xms -Xmx。一旦我增加了JVM的内存分配,CPU利用率就大幅下降了。

0
这很可能是由您在Tomcat上运行的应用程序引起的。当然,如果您的应用程序非常高流量,这也可能是原因。

0
我建议查看Tomcat日志文件,特别是名为catalina.out的文件。 在我的情况下,该文件随着错误消息不断扩大,显示“没有权限读取文件夹/var/lib/mysql”。我的应用程序包括一个监视服务,监视文件夹/var/lib/mysql。通过允许应用程序读取此文件夹,CPU使用率显著降低。高CPU使用率出现在系统更新后,可能会更改访问文件夹和文件的权限。因此,高CPU使用率的原因可能是外部于Web应用程序,也可能是外部于Tomcat容器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接