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
0
投稿
猜你喜欢
- 概述ReentrantReadWriteLock不知道大家熟悉吗?其实在实际的项目中用的比较少,反正我所在的项目没有用到过。Reentran
- 本文实例为大家分享了java制作简单验证码的具体代码,供大家参考,具体内容如下在这里我们需要用到java的画笔工具,所以我们需要导入以下包i
- 导语在使用flutter 自带图片组件的过程中,大家有没有考虑过flutter是如何加载一张网络图片的? 以及对自带的图片组件我们可以做些什
- 一、导入前言:导入必须用post请求具体原因在2中叙述1、Excel导入总结一下目标,就是要将excel中的数据行、逐一提取,最后得到一个l
- 一、场景描述仪器数据文件的格式包含Pdf、Word、Excel等多种,不同种格式的文件其数据的采集方式不同,因此定义仪器数据采集接口,并定义
- 1.根据单个分隔字符用split截取例如string st="GT123_1";string[] sArray=st.s
- 学C#的原因其实挺简单的,因为一直对游戏挺感兴趣,查了下比较流行的游戏引擎Unity的主要开发语言是C#,所以就决定从C#入手,学学面向对象
- 本文实例讲述了C#自定义针对URL地址的处理类。分享给大家供大家参考。具体分析如下:这个C#类是专门针对URL网址处理的类,可以对URL地址
- 1、AOP基本总结连接点(JoinPoint):连接点是程序运行的某个阶段点,如方法调用、异常抛出等切入点(Pointcut):切入点是Jo
- 最近有一款2048的游戏非常火,本文将来介绍一下使用OGEngine游戏引擎开发游戏2048。OGEngine引擎是开源的,我们很容易找到,
- 一、环境说明集群环境至少需要3个节点(也就是3台服务器设备):1个Master,2个Slave,节点之间局域网连接,可以相互ping通,下面
- 一,背景之所以会想到一个服务同时使用eureka和nacos,是因为遇到一个需求,配置数据是存储在nacos的配置中,然后使用该配置的服务却
- 1、使用场景 因为最近项目需要国际化,需要能够支持多种国际化语言,目前需要支持三种(法
- 本篇介绍在SpringBoot中配置Email服务的具体步骤,以及常见的异常分析。 具体案例以QQ邮箱以及QQ企业邮箱为例。QQ邮箱发送方式
- 我们先来看看公众号发放现金红包的效果:需要调用商户平台的接口,接口发放规则如下:1.发送频率限制——默认1800/min 2.发送个数上限—
- 一、背景介绍在微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLCo
- 定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。设计初衷:
- 一、项目概述之前有不少粉丝私信我说,能不能用Android原生的语言开发一款在手机上运行的游戏呢?说实话,使用java语言直接开发游戏这个需
- 本文实例讲述了java继承中的构造方法。分享给大家供大家参考。具体如下:继承中的构造方法: 1、子类的构造过程中必须调用其基类的构造方法。2
- 这篇文章主要介绍了JDK线程池和Spring线程池的使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值