昨天去了grafa 线上的监控看了看项目 突然发现cpu达到了70% (好久没关注) 然后开启了排查
现象图如下

这个项目没有其他的很耗时的操作 没有大量计算 而且接口数量 以及并发数量均没有很大 怀疑有异常 本来想着从grafa 监控中看下最近几个月 CPU使用率的变化 可惜因为数据量太大 线上没有保留这么长时间
出问题后临时的解决方案
开始进行深度代码排查
#1.获取到pods
kubectl get pods
#2.进入到容器
kubectl exec -it 容器名 bash
执行top 然后 M

占用CPU最大的进程pid为 然后 查询进程中消耗CPU最大线程
top -H -p 1



//等待被更新的缓存map
private static final Map<Long, Integer> userCacheMap = new ConcurrentHashMap<>();
//可用线程数
private static final Integer availableProcessors = Runtime.getRuntime().availableProcessors();
//任务执行线程池
private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(availableProcessors, availableProcessors + 1, 3, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1024), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "定时任务执行线程");
}
});
private class TaskThread extends Thread implements Runnable {
@Override
public void run() {
for (; ; ) {
//死循环 遍历map 存在数据进行处理 每处理一个数据 remove
Iterator<Map.Entry<Long, Integer>> iterator = userCacheMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Long, Integer> next = iterator.next();
Long userId = next.getKey();
Integer expireTime = next.getValue();
//丢入任务到线程池子
EXECUTOR.execute(new Task(userId, expireTime));
//任务数量
long taskCount = EXECUTOR.getTaskCount();
//完成任务数量
long completedTaskCount = EXECUTOR.getCompletedTaskCount();
//存活数量
int activeCount = EXECUTOR.getActiveCount();
LogUtil.info(log, LogUtil.LogType.INFO, "CacheUserServiceImpl.EXECUTOR",
"存活数量: {},任务数量: {},完成任务数量: {}", activeCount, taskCount, completedTaskCount);
iterator.remove();
}
}
}
}
复盘下 当时的设计方案
替换方案
总结: for(; ; ) 会占用大量CPU 尤其是for(; ; ) 里面遍历map 慎用