常见的cpu飙高原因:

  1. CAS 自旋一直重试导致 cpu 飙高 没有控制自旋次数;乐观锁
  2. 死循环;
  3. 阿里云 Redis 被注入非法程序,建议 Redis 端口不要能够被外网访问;
  4. 服务器被 DDOS 工具导致 cpu 飙高,可以通过限流、ip 黑名单、图形验证码防止机器模拟攻击。

由此我们知道在发生这类问题其解决关键就是找到发生cpu飙升的进程-->通过进程找到占用率最高的线程-->通过该线程找到对应的业务逻辑从而优化代码解决。固使用到线程池建议配置线程池名称方便后期维护。

首先我们先看看windows环境下的解决方法:

我们先运行一段测试代码模拟cpu飙高的问题场景

public class CeshiTest {

    public static void main(String[] args) {
        new Thread(() -> {
            while(true){
                System.out.println("跑代码中......");
            }
        },"thread-test-1").start();
    }
}

接着我们运行代码后打开任务管理器查看cpu使用率运行前后对比:

 前:

redis cpu 多少核 redis cpu高_java

 后:

redis cpu 多少核 redis cpu高_java_02

 我们发现cpu占用率明显飙升。随后我们打开jdk自带的一款性能分析和故障排除工具jvisualvm

工具路径在jdk安装路径下的(C:\Program Files\Java\jdk1.8.0_162\bin\jvisualvm.exe)

打开后找到我们运行的进程:

redis cpu 多少核 redis cpu高_jar_03

 接着在找到该进程的抽样器中查看cpu使用时间占比最高的线程

redis cpu 多少核 redis cpu高_服务器_04

 我们很快找到了问题的根源之后再去查看该线程对应的业务逻辑即可

我们再看看再linux环境下如何排查

 首先我们再linux中启动刚刚的测试代码

redis cpu 多少核 redis cpu高_服务器_05

然后执行命令 top -c 在服务器上cpu占用较高的进程:

redis cpu 多少核 redis cpu高_服务器_06

一研就找到了我们运行的测试代码进程,之后在对这一进程进行进一步排查,在这之前先介绍一款一款线上监控诊断工具Arthas(阿尔萨斯)

我们先通过命令下载该工具jar包在将jar启动起来:

curl -O https://arthas.aliyun.com/arthas-boot.jar

java -jar arthas-boot.jar

 

redis cpu 多少核 redis cpu高_java_07

 此时让我们选择要监控的进程,因为我们查到【2】出现问题,所以选择监控【2】就好了

redis cpu 多少核 redis cpu高_linux_08

 看到这代表启动成功并且监控我们正在运行的进程

然后我们在通过指令 thread -n 5 查看线程中cpu占用最多的5条线程:

redis cpu 多少核 redis cpu高_java_09

 由此我们也定位到了问题所在。

分析思路:

  1. 查看当前的操作系统中(top) 那个进程 cpu 使用率是最高的;
  2. 找到该操作系统中 最高使用率 进程 分析该进程里面具体线程 谁 cpu 使用率是最高 的
  3. 在根据线程名称 搜索“java 代码” 找到具体发生 cpu 飙高的代码 工具:使用 jvisualvmq.exe或者Arthas 工具

 注意:在企业真实环境中一般都会为自家项目开发一个服务器监控系统,并为服务器cup占用设置一个阈值(70%—85%),超过阈值就会报警通知运维人员,运维人员在查找到cpu飙升的服务器节点通知开发人员排查问题以防止挂掉。