概述
监控告警发现线上某台服务器cpu300%,下面记录排查过程
代码语言:javascript复制查看服务器情况
top
代码语言:javascript复制查看哪个线程cpu占用高
ps -mp 39954 -o THREAD,tid,time|sort -r|head -n 30
代码语言:javascript复制转换 线程id为16进制
printf "%xn" 40009
9c49
代码语言:javascript复制查看问题堆栈信息
jstack 39954|grep 9c49 -A 15
代码语言:javascript复制分析堆栈信息 由上图可以看出,是线程名为 “DubboSaveRegistryCache-thread-1” 线程占用线程过高,根据堆栈信息查看代码 dubbo 问题的代码位置在 AbstractRegistry 152 行
com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:152)
代码语言:javascript复制查看代码
private final ExecutorService registryCacheExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("DubboSaveRegistryCache", true));
public void doSaveProperties(long version) {
if (version < lastCacheChanged.get()) {
return;
}
if (file == null) {
return;
}
// Save
try {
File lockfile = new File(file.getAbsolutePath() ".lock");
//创建问题出现问题 抛出异常
if (!lockfile.exists()) {
lockfile.createNewFile();
}
//其他代码省略
} catch (Throwable e) {
if (version < lastCacheChanged.get()) {
return;
} else {
//异常处理 继续进入该方法 形成死循环
registryCacheExecutor.execute(new SaveProperties(lastCacheChanged.incrementAndGet()));
}
logger.warn("Failed to save registry store file, cause: " e.getMessage(), e);
}
}
private class SaveProperties implements Runnable {
private long version;
private SaveProperties(long version) {
this.version = version;
}
@Override
public void run() {
doSaveProperties(version);
}
}
分析代码可以看出,dubbo在创建缓存配置文件的时候出现错误,抛出异常后,继续放在线程池里面处理,形成了死循环
会是dubbo的问题吗? 会是dubbo的问题吗,我去github 搜索 issues 查看是否有人提出改问题,查询发现官方已经有人向官方提出这个问题 #3748
官方解决方案(2.7.2/2.5.10)修复
官方修复日志#3748
我们项目为什么会触发该问题
引起该问题的关键是缓存文件的配置 dubbo.registry.file ,查看我们配置发现 dubbo.registry.file 配置确实有问题,改正后消失,在官方没有修复这个错误之前的版本,我们使用这个配置一定要小心