tomcat cpu占用过高,系统负载高问题跟踪
线上8核 linux服务器,负载为8为正常情况,目前CPU负载过高,最高负载30多,平均负载在20左右,已经持续近一周,具体占用CPU资源的服务是tomcat_sc,占用CPU资源高达:720%
更改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?