java根据负载自动抓取jstack dump详情

作者:sdmei 时间:2021-09-05 01:47:05 

java应用CPU有波动,事后怎么分析?

java根据负载自动抓取jstack dump详情

目前我采用的方案是根据CPU负载自动执行jstack,并将文件上传到OSS。

 环境:阿里云 + k8s + springcloud + prometheus + oss

容器镜像安装python 2.7

涉及以下几个文件:

java根据负载自动抓取jstack dump详情

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调用脚本自动执行:

java根据负载自动抓取jstack dump详情

 最终生成的oss文件:

第一层目录:profiles

java根据负载自动抓取jstack dump详情

第二层目录:应用名称

java根据负载自动抓取jstack dump详情

第三层目录:具体jstack文件

文件名最后的数字是当时的CPU使用量,如166指1.66C

java根据负载自动抓取jstack dump详情

来源:https://blog.csdn.net/sdmei/article/details/127056953

标签:java,抓取,jstack,dump
0
投稿

猜你喜欢

  • SpringBoot 上传文件判空以及格式检验流程

    2023-01-19 05:07:36
  • Java实现导出ZIP压缩包的方法

    2023-05-06 04:58:57
  • 深入了解Java接口回调机制

    2023-11-09 15:52:05
  • Eureka源码阅读之环境搭建及工程结构

    2023-07-26 01:02:36
  • 使用Logback日志保存到相对路径的操作

    2021-10-11 16:42:30
  • Java设计模式之java装饰者模式详解

    2023-10-27 06:17:04
  • java ThreadGroup的作用及方法详解

    2022-02-03 16:49:01
  • Spring MVC中自定义拦截器的实例讲解

    2023-12-19 05:09:04
  • 解析Java内存分配和回收策略以及MinorGC、MajorGC、FullGC

    2023-02-06 08:22:19
  • java中的各种修饰符作用及范围

    2022-02-10 01:03:54
  • 从try-with-resources到ThreadLocal,优化你的代码编写方式

    2023-11-11 03:19:52
  • Java SpringBoot实现文件上传功能的示例代码

    2022-05-23 02:54:46
  • ThreadLocal的set方法原理示例解析

    2023-11-09 15:06:09
  • 获取JsonObject某一未知key的值操作

    2023-02-10 15:09:45
  • Java实现储存对象并按对象某属性排序的几种方法示例

    2022-05-04 18:05:57
  • java搭建ftp/sftp进行数据传递的全过程

    2023-11-29 15:08:10
  • 详解java接口基础知识附思维导图

    2023-11-09 10:07:28
  • Java服务限流算法的6种实现

    2022-04-03 04:52:51
  • Android ListView的Item点击效果的定制

    2023-06-21 11:46:01
  • Java判断变量是否为空问题的方法总结

    2023-02-03 12:23:09
  • asp之家 软件编程 m.aspxhome.com