zoukankan      html  css  js  c++  java
  • 线上服务器CPU100%排查

    测试代码:

    ```

    package jdktest;

    public class HoldCPUMain { //该车型简单占用cpu,4个用户线程,一个占用大量cpu资源,3个线程处于空闲状态
    public static class HoldCPUTask implements Runnable {
    @Override
    public void run() {
    while (true) {
    double a = Math.random() * Math.random(); //大量占用cpu
    }
    }
    }

    public static class LazyTask implements Runnable {
    @Override
    public void run() {
    try {
    while(true) {
    Thread.sleep(1000); //空闲线程
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    public static void main(String[] args) {
    new Thread(new HoldCPUTask()).start(); //开启线程,占用cpu
    new Thread(new LazyTask()).start(); //3个空闲线程
    new Thread(new LazyTask()).start();
    new Thread(new LazyTask()).start();
    }
    }

    ```

    某服务器上部署了若干tomcat实例,即若干垂直切分的Java站点服务,以及若干Java微服务,突然收到运维的CPU异常告警。

    问:如何定位是哪个服务进程导致CPU过载,哪个线程导致CPU过载,哪段代码导致CPU过载?

     

    步骤一、找到最耗CPU的进程PID

    工具top(可以配合Jps命令输出:13375 HoldCPUMain)

    方法

    · 执行top -c ,显示进程运行信息列表

    · 键入P (大写p),进程按照CPU使用率排序(大写M按内存排序)

    ·  

    输出:13375 root      20   0 2464304  21772  11488 S 98.7  1.2   6:31.28 java jdktest.HoldCPUMain 

     

    步骤二:找到该进程内最耗CPU的线程PID(假设步骤一得到进程pid是13375)

    工具top

    方法

    · top -Hp 13375 ,显示一个进程的线程运行信息列表

    · 键入P (大写p),线程按照CPU使用率排序

    输出:13386 root      20   0 2464304  21772  11488 R 99.0  1.2   7:20.99 java

     

    也可以安装sysstat,yum install -y sysstat,然后使用pidstat工具监控进程及线程的性能情况:

    pidstat -p 13375 1 3 -u -t,其中-p指定进程pid,参数1 3表示每秒采样1次,合计采样3次,-u表示对cpu使用率的监控,监视进程信息,加上-t进一步监视线程信息

    ```

    Average: UID TGID TID %usr %system %guest %CPU CPU Command
    Average: 0 13375 - 98.01 0.33 0.00 98.34 - java
    Average: 0 - 13375 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13376 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13377 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13378 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13380 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13381 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13382 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13383 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13384 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13385 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13386 98.01 0.00 0.00 98.01 - |__java
    Average: 0 - 13387 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13388 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 13389 0.00 0.00 0.00 0.00 - |__java
    Average: 0 - 15131 0.00 0.00 0.00 0.00 - |__java

    ```

     

    步骤三:将线程PID转化为16进制(假设步骤二得到线程pid是13386)

    工具printf

    方法printf  %x\n  13386

    这一步可以用计算器之所以要转化为16进制,是因为堆栈里,线程id是用16进制表示的。

     

    步骤四:查看堆栈,找到线程在干嘛(步骤三输出的线程pid的16进制是344a,a是小写)

    工具pstack/jstack/grep

    方法jstack 13375 | grep  0x344a  -C5 --color

    · 打印进程堆栈

    · 通过线程id,过滤得到线程堆栈

     

    找到了耗CPU高的线程对应的线程名称“Thread-0”,以及看到了该线程正在执行代码的堆栈。

    ```

    "Thread-0" #8 prio=5 os_prio=0 tid=0x00007fa86c0c9800 nid=0x344a runnable [0x00007fa8497d1000]

      java.lang.Thread.State: RUNNABLE
      at jdktest.HoldCPUMain$HoldCPUTask.run(HoldCPUMain.java:9)
      at java.lang.Thread.run(Thread.java:748)

    ``` 

    或使用jstack -l 13375 > /tmp/t.txt输出到文件

  • 相关阅读:
    leetcode-15 三数之和
    leetcode-113 路径之和
    leetcode-112 路径之和
    leetcode-1 两数之和
    leetcode-215 第k大元素
    leetcode 698 集合k划分
    编程之法之字符串
    LeetCode 830. Positions of Large Groups
    LeetCode 821. Shortest Distance to a Character
    LeetCode 213. House Robber II
  • 原文地址:https://www.cnblogs.com/kibana/p/11717159.html
Copyright © 2011-2022 走看看