本文共 3147 字,大约阅读时间需要 10 分钟。
【打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=$1count=5interval=5# 检查目录是否存在if [ ! -d "$TARGET_PATH" ]; then echo "目录不存在,开始创建..." mkdir -p "$TARGET_PATH" find "$TARGET_PATH" -type d -exec chmod 755 {} &else echo "目录已存在,无需创建。"fi# 获取本地IP并获取容器IDCONTAINER_ID=$(docker ps | grep tomcat | awk '{print $1}')if [ -z "$CONTAINER_ID" ]; then echo "$(date +%Y%m%d%H%M%S)未找到容器ID,请确认容器是否在运行" >> "$TARGET_PATH/log_file" exit 1fiecho "进入容器 $CONTAINER_ID ..." >> "$TARGET_PATH/log_file"docker exec -it "$CONTAINER_ID" bash# 查询进程PIDif [ ! -d "/app/jdk1.8.0_181/bin/" ]; then echo "$(date +%Y%m%d%H%M%S)目录不存在" >> "$TARGET_PATH/log_file" exit 1fiPID=$(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 1fiecho "找到的PID: $PID" >> "$TARGET_PATH/log_file"# 执行操作case $OPERATION in stack) for ((i=1; i<=count; i++)) do echo "$(date +%Y%m%d%H%M%S)导出堆栈到 $TARGET_PATH/${STACK_FILE_PREFIX}_$(curl -s http://localhost:8080 | head -n 1 | cut -d':' -f2)_${i}.txt" >> "$TARGET_PATH/log_file" docker exec -it "$CONTAINER_ID" bash -c "cd $JDK_DIR && ./jstack -l $PID > $TARGET_PATH/${STACK_FILE_PREFIX}_$(curl -s http://localhost:8080 | head -n 1 | cut -d':' -f2)_${i}.txt" sleep $interval done ;; dump) DUMP_FILE="${DUMP_FILE_PREFIX}_$(curl -s http://localhost:8080 | head -n 1 | cut -d':' -f2).hprof" echo "开始导出Dump文件..." >> "$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 [ $? != 0 ]; then echo "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 "无效的操作: $OPERATION" >> "$TARGET_PATH/log_file" echo "操作:stack 或 dump" >> "$TARGET_PATH/log_file" exit 1 ;;esacecho "操作完成。" >> "$TARGET_PATH/log_file" 【主要优化点】
容器IP获取方式优化
curl命令获取容器内网IP,避免IP地址冲突问题进程PID获取优化
脚本结构优化
-分隔长行脚本,提升可读性错误处理优化
环境适配优化
【问题解决】
针对$PID传入参数失败的问题,我在脚本中增加了以下优化:
进程名称匹配优化
异常处理优化
脚本执行流程优化
【后续优化建议】
日志管理优化
TARGET_PATH目录下单独创建日志文件,避免日志混淆脚本参数优化
脚本模块化优化
容器操作优化
通过以上优化,脚本在生产环境中的运行效率和稳定性得到了显著提升。
转载地址:http://vqefk.baihongyu.com/