性能测试-CPU使用率过高问题

一、通过jstack排查


1.通过top命令找到cpu占用高的应用程序进程

top


2.通过top -Hp pid查看该应用中占用CPU高的线程

top -Hp 5649

下图中是线程id


3.通过printf "%x\n" [线程id] 将线程高的线程号转为十六进制。
4.通过jstack过滤该十六进制的关键信息。jstack [进程号]|grep -A 10 [线程的16进制]

如下所示,定位到问题代码行

[root@VM-100-3-centos ~]# printf "%x\n" 6887
1ae7
[root@VM-100-3-centos ~]# jstack 5649 | grep -A 10 1ae7
"http-nio-18001-exec-107" #126 daemon prio=5 os_prio=0 tid=0x00007f48ec069000 nid=0x1ae7 runnable [0x00007f493cba1000]
   java.lang.Thread.State: RUNNABLE
        at com.tony.edu.perf.PostmanApplication.memory(PostmanApplication.java:48)
        at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
[root@VM-100-3-centos ~]#

二、通过Arthus(阿尔萨斯)排查

jstack排查,因为占用高的线程可能很快执行完了,手动操作,不容易定位,所以通常使用封装好的脚本或者工具,比如阿里的Arthus(阿尔萨斯)

Artuhs 是阿里巴巴开源的 java 的诊断工具

Arthas 地址:https://github.com/alibaba/arthas

官方文档:arthas

下载地址:Releases · alibaba/arthas · GitHub

1、下载后解压

2、进入解压目录

3、执行 java -jar arthas-boot.jar,启动

wyl@WYLdeMacBook-Air arthas-packaging-3.7.2-bin % pwd
/Users/wyl/Downloads/arthas-packaging-3.7.2-bin
wyl@WYLdeMacBook-Air arthas-packaging-3.7.2-bin % java -jar arthas-boot.jar 
[INFO] JAVA_HOME: /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
[INFO] arthas-boot version: 3.7.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 1827 sys_perf_01-0.0.1-SNAPSHOT.jar
  [2]: 1748 jd-gui-1.6.6-min.jar
  [3]: 1917 /Users/wyl/program/apache-jmeter-5.6.3/bin/ApacheJMeter.jar

4、要观察第哪个应用,输入哪个应用前面的序号。

如下示例,输入1

1
[INFO] arthas home: /Users/wyl/Downloads/arthas-packaging-3.7.2-bin
[INFO] Try to attach process 1827
Picked up JAVA_TOOL_OPTIONS: 
[INFO] Attach process 1827 success.
[INFO] arthas-client connect 127.0.0.1 3658
  ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.                           
 /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'                          
|  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.                          
|  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |                         
`--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'                          

wiki       https://arthas.aliyun.com/doc                                        
tutorials  https://arthas.aliyun.com/doc/arthas-tutorials.html                  
version    3.7.2                                                                
main_class org.springframework.boot.loader.JarLauncher                          
pid        1827                                                                 
time       2024-02-29 09:28:09                      

5、dashboard,进入看板,看板会自动刷新

6、ctrl+c,退出看板,输入 thread 57,查看该线程的问题代码行

附录、CPU 占用高的测试代码


import io.swagger.annotations.Api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@Api("- )
public class PostmanApplication {
  public static void main(String[] args) {
    SpringApplication.run(com.tony.edu.perf.PostmanApplication.class, args);
  }
  
  @GetMapping({"/cpu"})
  public ResponseEntity cpu() {
    long count = 1L;
    while (count < 10000000L) {
      count++;
      System.currentTimeMillis();
    } 
    return ResponseEntity.ok(");
  }
  
  @GetMapping({"/memory"})
  public ResponseEntity memory() throws InterruptedException {
    long startTime = System.currentTimeMillis();
    byte[] data = new byte[67108864];
    Thread.sleep(10L);
    return ResponseEntity.ok("+ data.length);
  }
}

启动服务后,访问 http://host:port/cpu,及可以触发

## 场景1  JVM的内存配置太少
## 1. 设置 512MB
java -Xmx512m -jar sys_perf_01-0.0.1-SNAPSHOT.jar 
## 2.  加大一倍内存 1200M
java -Xmx1200m -jar sys_perf_01-0.0.1-SNAPSHOT.jar 


## 场景2 WEB服务器 提供的 线程数 过少
## 1. WEB服务器 提供的 线程数 过少
java -Xmx1200m -jar  -Dserver.tomcat.max-threads=1 sys_perf_01-0.0.1-SNAPSHOT.jar 
## 2. 
java -Xmx1200m -jar  -Dserver.tomcat.max-threads=100 sys_perf_01-0.0.1-SNAPSHOT.jar 

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值