Linux线上CPU占用过高排查
程序员文章站
2024-01-23 12:16:46
...
问题是这样的,将项目部署到服务器上后,发现应用程序的响应速度非常慢,于是开始进行了排查。
TOP
首先查看系统资源占用信息,TOP看一下
发现正在运行的JAVA项目CPU占用率很高,百分之110左右了,那么问题一定出在这个程序中
Ps -mp pid -o THREAD,tid,time
再通过ps命令查看这个程序的线程信息,tid代码线程ID,time代表这个线程的已运行时间
由上面TOP可知进程ID为17569
于是可以看到这个进程中有3个线程的CPU占用率很高,并且它们目前也运行了13分钟了,它们的TID分别为17569
进制转换,2HEX
再将这3个TID转为16进制,为等会在jstack中查找方便
Printf “%x\n” number
得到这个数的16进制为44a1
jstack查看进程信息
有了线程ID的16进制后,再在jstack中查看进程堆栈信息(之所有拿到TID信息,主要是为了查找方便)
通过jstack -pid 再grep查询
从这里能看出,这3个线程目前还处于运行状态的
再通过jstack查看详细点的信息
其中显示出了较为详细的代码信息
本地代码问题排查
再通过回到代码中查看CanalLauncher.main方法
通过code review发现,canal的代码中有一段连接判断的while循环,一直在调用,修改增加Thread.sleep(),问题解决
public static void main(String[] args) {
try {
running = true;
logger.info("## set default uncaught exception handler");
setGlobalUncaughtExceptionHandler();
logger.info("## load canal configurations");
String conf = System.getProperty("canal.conf", "classpath:canal.properties");
Properties properties = new Properties();
RemoteConfigLoader remoteConfigLoader = null;
if (conf.startsWith(CLASSPATH_URL_PREFIX)) {
conf = StringUtils.substringAfter(conf, CLASSPATH_URL_PREFIX);
properties.load(CanalLauncher.class.getClassLoader().getResourceAsStream(conf));
} else {
properties.load(new FileInputStream(conf));
}
remoteConfigLoader = RemoteConfigLoaderFactory.getRemoteConfigLoader(properties);
if (remoteConfigLoader != null) {
// 加载远程canal.properties
Properties remoteConfig = remoteConfigLoader.loadRemoteConfig();
// 加载remote instance配置
remoteConfigLoader.loadRemoteInstanceConfigs();
if (remoteConfig != null) {
properties = remoteConfig;
} else {
remoteConfigLoader = null;
}
}
final CanalStater canalStater = new CanalStater();
canalStater.start(properties);
if (remoteConfigLoader != null) {
remoteConfigLoader.startMonitor(new RemoteCanalConfigMonitor() {
@Override
public void onChange(Properties properties) {
try {
// 远程配置canal.properties修改重新加载整个应用
canalStater.destroy();
canalStater.start(properties);
} catch (Throwable throwable) {
logger.error(throwable.getMessage(), throwable);
}
}
});
}
while (running) {
Thread.sleep(1000);
}
if (remoteConfigLoader != null) {
remoteConfigLoader.destroy();
}
} catch (Throwable e) {
logger.error("## Something goes wrong when starting up the canal Server:", e);
}
}
重新打包mvn clean install -Dmaven.test.skip -Denv=release,上传替换问题解决。
读者看到这里,基本上猜出个大概,是的就是阿里的mysql跨机房数据同步中间件canal