首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

tomcat cpu占用过高,系统负载高有关问题跟踪

2013-08-16 
tomcat cpu占用过高,系统负载高问题跟踪线上8核 linux服务器,负载为8为正常情况,目前CPU负载过高,最高负载

tomcat cpu占用过高,系统负载高问题跟踪

线上8核 linux服务器,负载为8为正常情况,目前CPU负载过高,最高负载30多,平均负载在20左右,已经持续近一周,具体占用CPU资源的服务是tomcat_sc,占用CPU资源高达:720%

  • 使用jconsole去跟踪

    更改catalina.sh 启动设置:

    ?$ CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8933 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=$server_ip";

    hostname -i 为127.0.0.1 ??

    测试服务器配置完后,在本机使用jconsole连接,输入测试服务器帐号密码即可连上。网上资料说要改hostname,没有更改hostname也可行

    线上先开了服务器端口,又开了 本机端口,telnet可以连上,但jconsole无法连接,查google,说:

    the jvm you're trying to connect to actually exposes *two* ports, the one specified via -Dcom.sun.management.jmxremote.port, and some other one. The 2nd one is random, but jconsole wants to connect to it, so if you have a firewall, and you've only opened up the above port, you're hosed. ?

    ?只开放了一个端口就不可以?必须外网服务器所有端口都对内网开放?继续跟踪。

    jmap jconsole jstack都是java自带的jmx 问题跟踪工具, 可以学习一下帮助分析定位内存溢出 程序死锁之类的程序问题

    使用 jmap ?查看内存状况

    jmap -histo:live pid

    服务自建类的数量并不多

    jstack 跟踪堆栈也没看出个所以然

    继续jconsole调查 ?google “jconsole remote set random port to certain” 找到一篇像样的文章:

    ?http://www.componative.com/content/controller/developer/insights/jconsole3/

    于是写了servlet去注册指定端口 未果

    在测试机上先试试 ?写java文件:

    import java.rmi.registry.LocateRegistry;
    import javax.management.MBeanServer;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    import java.io.IOException;
    import java.lang.management.ManagementFactory;
    import java.net.MalformedURLException;

    public class JmxTest {
    public static void main(String[] args) {
    MBeanServer mbeanServer =
    ManagementFactory.getPlatformMBeanServer();

    JMXServiceURL url = null;
    try {
    url = new JMXServiceURL(
    "service:jmx:rmi://localhost:12199/jndi/rmi://localhost:8933/jmxrmi");
    } catch (MalformedURLException e) {
    ? e.printStackTrace();
    }

    JMXConnectorServer connectorServer =
    null;
    try {
    connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
    } catch (IOException e) {
    ? e.printStackTrace();
    }

    try {
    System.setProperty("java.rmi.server.randomIDs", "true");
    LocateRegistry.getRegistry(8933);
    connectorServer.start();
    } catch (IOException e) {
    ? e.printStackTrace(); ?
    }

    }
    }

    出现 java.rmi.AccessException: Cannot modify this registry 错误

    注释掉 ?catalina.sh的启动设置? ?-Dcom.sun.management.jmxremote.port=8933 ?也不行

    ?最终放弃了jconsole

    ? ? ? 使用 java.lang.management..ThreadMXBean?
    用焱哥转发 新阳提供的 jsp页面 分析性能问题,主要是看线程阻塞情况
    主要代码:
    ThreadMXBean tm = ManagementFactory.getThreadMXBean();
    tm.setThreadContentionMonitoringEnabled(true);
    <%
    long [] tid = tm.getAllThreadIds();
    ThreadInfo [] tia = tm.getThreadInfo(tid, Integer.MAX_VALUE);

    long [][] threadArray = new long[tia.length][2];

    for (int i = 0; i < tia.length; i++) {
    long threadId = tia[i].getThreadId();

    long cpuTime = tm.getThreadCpuTime(tia[i].getThreadId())/(1000*1000*1000);
    threadArray[i][0] = threadId;
    threadArray[i][1] = cpuTime;
    }

    检测到如下线程问题:
    Thread ID: 89
    Thread Name: http-6080-Processor73
    Thread State: RUNNABLE
    Thread Lock Name: null
    Thread Lock Owner Name: null
    Thread CPU Time: 35678 sec
    Stack Info: (depth:31)
    +java.util.HashMap.get(HashMap.java:303)
    +com.netqin.baike.server.nqrs.CloudSecurityCommand.writePkgsLog(CloudSecurityCommand.java:466)
    +com.netqin.baike.server.nqrs.CloudSecurityCommand.execute(CloudSecurityCommand.java:153)
    +com.netqin.baike.server.BaikeServer.service(BaikeServer.java:64)
    +sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
    CPU占用时间达到 35678秒 ,到下午到了50000秒左右,tomcat的CPU占用达到了200%
    分析代码,发现是单例bean中使用了 hashmap 作为类对象,多线程访问时 类成员hashmap并不是线程安全的 非单例,引起了问题。更正代码后,截至目前 12小时以后没有发现问题,继续监控

  • 热点排行