java根据负载自动抓取jstack dump详情
作者:sdmei 发布时间:2021-09-05 01:47:05
标签:java,抓取,jstack,dump
java应用CPU有波动,事后怎么分析?
目前我采用的方案是根据CPU负载自动执行jstack,并将文件上传到OSS。
环境:阿里云 + k8s + springcloud + prometheus + oss
容器镜像安装python 2.7
涉及以下几个文件:
oss相关的文件包括:oss客户端和配置文件;
逻辑主要在脚本:mon_cpu_jstack.py
两个参数:CPU阈值,profile环境(prod \ test等)
每10s 执行一次脚本(跳过起初的3分钟,因为应用启动时CPU负载高是正常的);
通过top获取CPU,超过阈值则执行jstack;
如果CPU消耗最大进程是GC,拉取jmap信息;
每小时最大执行3次jstack(太多无意义);
生成文件后通过oss客户端上传OSS;
# more mon_cpu_jstack.py
# -*- coding: utf-8 -*-
import time
import commands as cm
import os,sys
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)
if len(sys.argv) != 3:
print 'Usage: ' + sys.argv[0] + ' [cpu_threshold] [profiles]'
sys.exit(1)
cpu_th = float(sys.argv[1])
profiles = sys.argv[2]
base_dir = '/opt/perf'
time_list = []
def oss_upload(app_name,logfile):
comm_upload = base_dir + '/ossutil64 -c ' + base_dir + '/ossutilconfig cp ' + logfile + ' oss://k8s-jstack-log/' + profiles + '/' + app_name + '/'
comm_delete = 'rm -f ' + logfile
os.system(comm_upload)
time.sleep(1)
os.system(comm_delete)
def mon_and_catch():
global time_list
# up to 3 times hourly
if len(time_list) == 3:
if time.time() - time_list[-1] <= 3600:
return
host_name = cm.getoutput('hostname')
java_pid = cm.getoutput('top -b -n1 | grep java|awk \'{printf $1}\'')
if (java_pid == ''):
print 'no java_pid'
return
cpu_pct_str = cm.getoutput('top -b -p ' + java_pid + ' -n1 | tail -1 |awk \'{printf $9}\'')
cpu_pct = float(cpu_pct_str)
time_str = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
log_name = base_dir + '/' + host_name + '_' + time_str + '_cpu_' + cpu_pct_str.split('.')[0] + '.log'
if(cpu_pct > cpu_th):
time_list.insert(0, time.time())
time_list = time_list[:3]
os.system('top -Hbp' + java_pid + ' -n1 >> ' + log_name)
os.system('echo >> ' + log_name)
os.system('jstack -l ' + java_pid + ' >> '+log_name)
# if cpu is used by gc, exec jmap
top_thread_id = cm.getoutput('cat ' + log_name + ' | grep java | head -1 | awk \'{print $1}\'')
top_thread_id_hex = "0x" + cm.getoutput('printf \'%x\n\' ' + top_thread_id) + " "
top_thread_gc = cm.getoutput('cat ' + log_name + ' | grep "' + top_thread_id_hex + '" | grep "GC" | wc -l')
if top_thread_gc == '1':
os.system('echo >> ' + log_name)
os.system('jmap -histo:live ' + java_pid + ' | head -100 >> ' + log_name)
# get app_name from hostname
hostname_list = host_name.split('-')
app_name_list = hostname_list[:len(hostname_list)-2]
app_name='-'.join(app_name_list)
if app_name[-1] in ['1','2']:
app_name = app_name[:len(app_name)-1]
oss_upload(app_name, log_name)
if __name__ == '__main__':
i = 0
while (True):
# skip at startup
if i > 18:
mon_and_catch()
time.sleep(10)
i = i + 1
poststart.sh调用上述python脚本(profile直接从环境变量中获取)
# more poststart.sh
cpu_th=$1
nohup python -u /opt/perf/mon_cpu_jstack.py ${cpu_th} ${spring_profiles_active} > /opt/perf/poststart.log 2>&1 &
exit 0
通过postStart调用脚本自动执行:
最终生成的oss文件:
第一层目录:profiles
第二层目录:应用名称
第三层目录:具体jstack文件
文件名最后的数字是当时的CPU使用量,如166指1.66C
来源:https://blog.csdn.net/sdmei/article/details/127056953


猜你喜欢
- 前言Java中容器对象主要用来存储其他对象,根据实现原理不同,主要有3类常用的容器对象:1、ArrayList 使用数组结构存储容器中的元素
- 在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能
- 前面我们讲到了Spring在进行事务逻辑织入的时候,无论是事务开始,提交或者回滚,都会触发相应的事务事件。本文首先会使用实例进行讲解Spri
- 很多时候在进行C#项目的实际开发中,会需要根据条件来设置节点不可勾选,查看DevExpress文档发现通过其CustomDrawNodeCh
- java中的set接口有如下的特点:不允许出现重复元素;集合中的元素位置无顺序;有且只有一个值为null的元素。因为java中的set接口模
- 一般来说课本上的数据结构包括数组、单链表、堆栈、树、图。我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用
- 这是一篇入门级文章,高手请略过。在这篇文章中我们将学习如何用 Java 对图像进行剪裁并将剪裁出来的部分单独保存到文件中。我们将通过以下步骤
- 我们平时在开发系统时,一般我们的系统工程会被分为多个模块,一个原因是方便协同开发,系统间解耦,另外一个很重要的原因是:别的系统需要依赖我们系
- 用户可以自定义打印某一年的年历,即:把某一年的日历全部打印出来如把2013年的年历打印出来如下:January 2013&nbs
- 本文实例为大家分享了Android仿QQ讨论组头像展示的具体代码,供大家参考,具体内容如下一、效果图二、实现基本实现过程:1.将原图片读取为
- 1、使用第三方类库 HtmlAgilityPack官方网址:https://html-agility-pack.net/?z=codeple
- Android中在sqlite插入数据的时候默认一条语句就是一个事务,因此如果存在上万条数据插入的话,那就需要执行上万次插入操作,操作速度可
- 1 前言任何一门语言都需要基本的流程控制语句,其思想也符合人类判断问题或做事的逻辑过程。什么是流程控制呢?流程就是做一件事情的顺序,或者说是
- 带搜索的ComboBox就是给ComboBox一个依赖属性的ItemSource,然后通过数据源中是否包含要查询的值,重新给ComboBox
- 最近有个同事在调用一个类库中的方法时遇到了一个问题,异常信息如下:尝试释放正在使用的RCW,活动线程或其他线程上正在使用该 RCW,释放正在
- 前言最近在工作中遇到了这么一个需求:如何实现 Android 应用前后台切换的监听?下面来一起看看详细的介绍:iOS 内边是可以实现的,Ap
- 递归出现栈溢出stackoverflow递归是个不断回调方法的过程,使方法一遍遍的压入栈中,递归次数多了,栈满了也就溢出了。默认的栈大小是1
- 本文实例为大家分享了Android原生视频播放VideoView的具体代码,供大家参考,具体内容如下布局文件activity_video.x
- 常量是固定值,程序执行期间不会改变。常量可以是任何基本数据类型,比如整数常量、浮点常量、字符常量或者字符串常量,还有枚举常量。常量可以被当作
- 1.user实体package com.demo.dto;public class User { private Integer