Jorgen's blog Jorgen's blog
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
收藏
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

jorgen

Love it, make mistakes, learn, keep grinding.
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
收藏
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 平台架构
  • 技术选型
  • 开发脚手架
  • UI规范
  • 开发规范
  • 代码分支管理模型
  • 需求分析与管理
  • 权限设计
  • 树形组织设计
  • 协议设计
  • 指令交互
  • OTA
  • 规则引擎
  • 数据流转
  • 报告生成与导出
  • 监控设备接入
  • 时序数据库
  • 平台监控
  • 云⛈
  • 接口设计
  • 安全传输
  • CI&CD
  • 缓存
  • 消息处理引擎
  • 性能调优🔥
  • 线上事故🔥
    • 背景
    • 准备
    • jstack查看堆栈信息
    • Arthas(阿尔萨斯)
    • show-busy-java-threads
  • 混合式开发记录
  • 推送服务
  • 机器人通信协议
  • 数据分析
  • flink模板工程
  • 实时调度
  • 机器人模块化设计
  • STM32入门
  • 开发日志
Jorgen
2023-02-18
目录

线上事故🔥

# 背景

最近测试服出现了CPU异常高的情况,占用率接近 100%,所以写篇文章简单地记录下碰到这种情况,该如何去定位导致CPU异常的代码,下文介绍了几种比较常用的工具。

# 准备

我们先准备一个测试项目,此处使用的是一个简单的 springboot 的 web 项目。

package com.example.deadcycle;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ConcurrentHashMap;

@SpringBootApplication
@RestController
@RequestMapping("/")
public class DeadCycleApplication {

    public static void main(String[] args) {
        SpringApplication.run(DeadCycleApplication.class, args);
    }

    @GetMapping("/test")
    public String cpuTest() {
        int i = 2;
        while (i > 0) {
            new Thread(this::testTrue).start();
            i--;
        }
        return "success";
    }

    public ConcurrentHashMap map = new ConcurrentHashMap();

    public void testTrue() {
        while (true) {
            int i = 200000;
            while (i > 0) {
                map.put(Thread.currentThread().getName() + i, i);
                i--;
            }
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

打包后放到我买的云服务上运行:nohup java -jar demo.jar &

在进行本地访问,运行死循环的那段逻辑:curl 127.0.0.1:8756/test

此时使用 top 查看服务器的 CPU 信息,发现已经使用了 50%,而且是被我们刚才启动的 java 进程占用的,PID 为 3281706。 demo

下面就介绍几种简单的方法来定位有问题的代码。

# jstack查看堆栈信息

此处原生的方法其实就是使用 jdk 自带的工具(需要注意的是:Linux自带的 openJdk 是没有的)。 这是最基础并且最有效的方法,因为很多其它的工具其实还是使用的 openJdk 的这一系列命令,只不过封装得更为友好了而已。

上文已经查出来是3281706这个进程有问题。

所以我们就先查看下3281706下面是哪些线程在搞鬼:top -Hp 3281706

排查CPU占用过高的问题

从面板上我们乍一看,发现了三个异常的线程,PID分别为3282201、3282202。

要使用 jstack 查看他们的堆栈信息,首先要将 PID 转为 16进制:printf "%x\n" 3282201 3282202 排查CPU占用过高的问题

接下来就可以查看堆栈信息了,下面以3282201这个为例(注意:16进制要在最前面添加0x):jstack 3281706 | grep '0x321519' -A10

排查CPU占用过高的问题

问题代码立马就找到了。

另外,我们也可以将堆栈信息打印下来:jstack 3281706 > cputest.dump然后使用 cat 等命令工具进行过滤查看:cat -n cputest.dump | grep -A10 '0x321519'

# Arthas(阿尔萨斯)

上文的方法比较繁琐,下面就使用目前特别火的工具来排查下问题。

Arthas 是阿里巴巴开源的一个针对 java 程序的线上诊断工具,全平台支持,有命令行,也有web端,功能非常强大。

官网:地址 (opens new window)。

我们先安装基础工具:curl -O https://alibaba.github.io/arthas/arthas-boot.jar

也可以从 gitee 下载:curl -O https://arthas.gitee.io/arthas-boot.jar

运行:java -jar arthas-boot.jar

Arthas 会罗列出当前服务器上面的所有 Java 进程,我们选择一个我们想要查看的就行,比如此处输入1即可。另外,首次运行是需要下载一些依赖工具的,如果无法下载,也可以使用全量安装。此时左下角也已经变成了 [arthas@3281706],这个3281706 就是我们想要查看的程序继进程

排查CPU占用过高的问题

控制台输入 dashboard 即可查看: 排查CPU占用过高的问题

从上面的面板上,其实很容易发现有两个异常的线程,ID 分别为 20 和 21,另外还有异常的 GC 信息。

输入 Ctrl c 退出面板,接下来我们就来为ID为20的这个线程把把脉,输入 thread 20 查看线程的详细信息:

排查CPU占用过高的问题

问题代码就这样被定为了,so cool !

输入 quite 即可退出 Arthas。

另外,Arthas 的功能十分强大,远不限于此,比如自带 jad 反编译工具等,此处暂不赘述

# show-busy-java-threads

下面的这个工具,也是很常用并且很强大的,而且 show-busy-java-threads 只是useful-scripts 工具包中的工具之一。

下载:地址 (opens new window) 上传 bin 文件夹下的 show-busy-java-threads 脚本到服务器上去。

赋予权限:chmod +x show-busy-java-threads

运行: ./show-busy-java-threads

排查CPU占用过高的问题

从上图中就看到了异常代码的出处。

其他命令:

show-busy-java-threads -c 3:3为n,指定显示最耗cpu使用率前3的线程。show-busy-java-threads -c 3 -p 17376:展示进程17376耗费CPU组多的3个线程。

此文简单介绍了三种排查服务器CPU负载高的方案,其实使用体验都还是比较简单的,但是有两点是万变不离其宗的,那就是底层工具的使用和解决问题的流程。

从打印的堆栈信息中我们就可以看出,信息都长的差不多,所以也可以看出,底层所使用的工具都一样,其实都是 jdk 的 jstack 等工具。

一般的解决流程

查看 CPU 高负载的进程查看具体的线程找到对应进程的堆栈信息在上述的堆栈信息中过滤出对应线程的信息

#jstack#Arthas#show-busy-java-threads
上次更新: 2023/02/19, 11:42:06
性能调优🔥
混合式开发记录

← 性能调优🔥 混合式开发记录→

最近更新
01
STM32入门
03-09
02
ADB调试
03-09
03
微信小程序学习记录
02-09
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jorgen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式