【打dunp和堆栈的脚本】
背景:
最近在要写一个打dunp和堆栈的脚本,方便后期操作的
(环境:使用了的容器的,在宿主机上跑脚本)
脚本:
#!/bin/bash
# 定义常量
TARGET_PATH="xxxxx"
JDK_DIR="/app/jdk1.8.0_181/bin/"
STACK_FILE_PREFIX="stack"
DUMP_FILE_PREFIX="heap_dump"
OPERATION=$1
# 设置导出次数
count=5
# 设置导出间隔(秒)
interval=5
#检查目录是否存在这里要写到容器的文件中
#if [ ! -d "$TARGET_PATH" ]; then
# echo "目录不存在,开始创建..."
# # 创建级联目录
# mkdir -p "$TARGET_PATH"
# # 设置权限为 755
# find "$TARGET_PATH" -type d -exec chmod 755 {} +
#else
# echo "目录已存在,无需创建。"
#fi
#获取本地ip
#容器操作
# 1. 获取容器ID并进入容器
CONTAINER_ID=$(docker ps | grep tomcat | grep -v grep | awk '{print $1}')
if [ -z "$CONTAINER_ID" ]; then
echo "$(date +%Y%m%d%H%M%S)未找到容器ID,请确认容器是否在运行" >> "$TARGET_PATH/$log_file"
exit 1
fi
echo "$(date +%Y%m%d%H%M%S)进入容器 $CONTAINER_ID ..." >> "$TARGET_PATH/$log_file"
docker exec -it "$CONTAINER_ID" bash
#2. 查询进程PID
cd /app/jdk1.8.0_181/bin/ || { echo "$(date +%Y%m%d%H%M%S)目录不存在" >> "$TARGET_PATH/$log_file"; exit 1; }
#进行ps查询,提取PID
PID=$(ps -ef | grep '[t]omcat.*startup.Bootstrap start' | awk '{print $2}')
if [ -z "$PID" ]; then
echo "$(date +%Y%m%d%H%M%S)未找到相应的tomcat进程" >> "$TARGET_PATH/$log_file"
exit 1
fi
echo "找到的PID: $PID"
# 执行操作
case $OPERATION in
stack)
# 循环导出堆栈
for (( i=1; i<=count; i++ ))
do
echo "$(date +%Y%m%d%H%M%S)导出堆栈到 $TARGET_PATH/${STACK_FILE_PREFIX}_$(APP_IP)_${i}.txt" >> "$TARGET_PATH/$log_file"
docker exec -it $CONTAINER_ID bash -c "cd $JDK_DIR && ./jstack -l $PID > $TARGET_PATH/${STACK_FILE_PREFIX}_$(APP_IP)_${i}.txt"
;;
# 等待指定时间
sleep $interval
done
dump)
DUMP_FILE="${DUMP_FILE_PREFIX}_$(APP_IP).hprof"
echo "$(date +%Y%m%d%H%M%S)导出 Dump 到 $TARGET_PATH/$DUMP_FILE" >> "$TARGET_PATH/$log_file"
docker exec $CONTAINER_ID bash -c "cd $JDK_DIR && ./jmap -dump:format=b,live,file=$TARGET_PATH/$DUMP_FILE $PID"
if [ $? -ne 0 ]; then
echo "$(date +%Y%m%d%H%M%S)jmap 导出 Dump 失败,尝试使用 jcmd..." >> "$TARGET_PATH/$log_file"
docker exec $CONTAINER_ID bash -c "cd $JDK_DIR && ./jcmd $PID GC.heap_dump $TARGET_PATH/$DUMP_FILE"
fi
;;
*)
echo "$(date +%Y%m%d%H%M%S)无效的操作: $OPERATION" >> "$TARGET_PATH/$log_file"
echo "$(date +%Y%m%d%H%M%S)操作: stack 或 dump" >> "$TARGET_PATH/$log_file"
exit 1
;;
esac
echo "$(date +%Y%m%d%H%M%S)操作完成。" >> "$TARGET_PATH/$log_file"
问题:
本人在我们的生产环境执行的时候,其中在$PID传入参数的时候,并没有实现的真正的入参,用了很多方法,都没有传入成功
将参数写死,是没有问题的
这里还需要后续优化