博客
关于我
【打dunp和堆栈的脚本】
阅读量:799 次
发布时间:2023-04-02

本文共 3147 字,大约阅读时间需要 10 分钟。

【打dunp和堆栈的脚本优化】

最近在生产环境中需要编写一个打dunp和堆栈的脚本,便于后期操作。以下是我针对脚本进行的优化以及问题解决方案。

【背景】

目前我们使用了容器的环境,在宿主机上运行脚本。脚本需要完成以下操作:

  • 获取容器中的JDK路径
  • 获取Tomcat进程的PID
  • 根据操作类型(stack或dump)执行相应的命令
  • 记录操作日志并处理异常情况
  • 【脚本优化】

    经过反复优化,我对脚本进行了以下改进:

    #!/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"
    find "$TARGET_PATH" -type d -exec chmod 755 {} &
    else
    echo "目录已存在,无需创建。"
    fi
    # 获取本地IP并获取容器ID
    CONTAINER_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 1
    fi
    echo "进入容器 $CONTAINER_ID ..." >> "$TARGET_PATH/log_file"
    docker exec -it "$CONTAINER_ID" bash
    # 查询进程PID
    if [ ! -d "/app/jdk1.8.0_181/bin/" ]; then
    echo "$(date +%Y%m%d%H%M%S)目录不存在" >> "$TARGET_PATH/log_file"
    exit 1
    fi
    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" >> "$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
    ;;
    esac
    echo "操作完成。" >> "$TARGET_PATH/log_file"

    【主要优化点】

  • 容器IP获取方式优化

    • 使用curl命令获取容器内网IP,避免IP地址冲突问题
    • 增加容器IP的唯一性标识
  • 进程PID获取优化

    • 增加了对PID的多次查找,确保PID的正确性
    • 提供了更详细的错误信息指导
  • 脚本结构优化

    • 使用-分隔长行脚本,提升可读性
    • 增加了脚本的注释,方便后期维护
  • 错误处理优化

    • 增加了多种错误检查,确保脚本稳定运行
    • 提供了详细的日志记录,方便排查问题
  • 环境适配优化

    • 增加了对JDK目录的多次检查,避免路径错误
    • 提供了对容器状态的实时监控
  • 【问题解决】

    针对$PID传入参数失败的问题,我在脚本中增加了以下优化:

  • 进程名称匹配优化

    • 根据实际进程名称进行匹配,避免因为进程名称变化导致PID获取失败
    • 增加了对PID的多次查找,确保PID的正确性
  • 异常处理优化

    • 在PID获取失败时,提供了更详细的错误信息指导
    • 增加了对PID的可用性检查,避免因PID不存在而导致脚本失败
  • 脚本执行流程优化

    • 增加了对脚本步骤的验证,确保每一步都正常进行
    • 提供了对脚本输出的实时监控,方便排查问题
  • 【后续优化建议】

  • 日志管理优化

    • 建议在TARGET_PATH目录下单独创建日志文件,避免日志混淆
    • 将日志文件归类存储,方便日后查找和管理
  • 脚本参数优化

    • 建议在脚本中增加更多的参数设置,支持不同的应用场景
    • 提供参数帮助信息,提升用户体验
  • 脚本模块化优化

    • 将脚本拆分成不同的功能模块,提升代码复用性
    • 增加函数调用,提高脚本的可维护性
  • 容器操作优化

    • 建议增加对容器状态的实时监控,避免因容器状态变化导致脚本失败
    • 提供容器退出机制,确保脚本在容器关闭时能够优雅退出
  • 通过以上优化,脚本在生产环境中的运行效率和稳定性得到了显著提升。

    转载地址:http://vqefk.baihongyu.com/

    你可能感兴趣的文章
    Outlook Express could not be started
    查看>>
    outlook express 故障
    查看>>
    outlook gmail setting
    查看>>
    spring自定义线程池 逻辑 配置 ThreadPoolTaskExecutor corePoolSize maxPoolSize queueCapacity rejectedExecutionHa
    查看>>
    Outlookbar-style menu interface
    查看>>
    outlook中XXX.xls附件无法打开解决办法
    查看>>
    Outlook存档
    查看>>
    Outlook替代Hotmail:社交很重要,但邮箱是根本
    查看>>
    Outlook邮箱怎么方便地发送超大附件?
    查看>>
    outputStream转inputStream
    查看>>
    overflow:hidden不生效问题
    查看>>
    overlay(VLAN,VxLAN)、underlay网络、大二层概述
    查看>>
    Overload和Override的区别?
    查看>>
    Ovirt添加ISO存储域
    查看>>
    OWASP 2025 年 10 大漏洞 – 被利用/发现的最关键弱点,从零基础到精通,收藏这篇就够了!
    查看>>
    OWASP漏洞原理启航(第一课)
    查看>>
    OWASP漏洞原理<最基础的数据库 第二课>
    查看>>
    OWL本体语言
    查看>>
    P with Spacy:自定义文本分类管道
    查看>>
    Spring自动装配Bean
    查看>>