restart.sh 脚本是一个用于 Java 应用程序的重启脚本,支持以下功能:

主要功能

  1. 应用程序重启
    • 自动停止现有的 Java 应用进程
    • 启动新的 Java 应用实例
    • 支持优雅停止和强制杀死进程
  2. 进程管理
    • 通过进程名称查找并停止旧进程
    • 设置停止超时时间(20秒)
    • 如果优雅停止失败,会强制杀死进程
  3. 启动监控
    • 启动后监控进程状态
    • 设置启动超时时间(20秒)
    • 启动成功/失败的状态反馈

配置支持

  1. Java 环境配置
    • 优先使用 JAVA_HOME 环境变量中的 Java
    • 如果未设置,则使用系统默认的 java 命令
  2. JVM 参数配置
    • 内存设置-Xms4g -Xmx8g (初始4GB,最大8GB堆内存)
    • 垃圾回收: 使用 G1 垃圾收集器
    • 错误处理: 支持堆转储配置(当前已注释)
    • 系统属性: Spring 开发环境配置,端口9000
  3. 日志管理
    • 应用输出日志:./baseLogs/app.log
    • GC 日志:./baseLogs/gc.log
    • 启动记录:./baseLogs/startRecord.log
    • 错误转储目录:./dump/

应用配置

  • JAR 文件web-app-starter-2.2.0-SNAPSHOT.jar
  • 运行环境: Spring Boot 应用,开发环境
  • 服务端口: 9000
  • 进程标识: 通过 JAR 文件名识别进程

安全特性

  • 使用 set -euo pipefail 确保脚本在出错时立即退出
  • 自动创建必要的目录
  • 检查 JAR 文件是否存在
  • 详细的日志记录和状态输出

这个脚本特别适用于 Spring Boot 应用的生产环境部署和维护,提供了完整的启停控制和监控功能。

#!/bin/bash
set -euo pipefail

APP_NAME="填写jar名称.jar"
APP_DIR="$(cd "$(dirname "$0")" && pwd)"
JAR_PATH="${APP_DIR}/${APP_NAME}"
RUN_TAG="${APP_NAME}"
# JAVA_BIN 优先用 JAVA_HOME,否则用系统 java
if [ -n "${JAVA_HOME:-}" ] && [ -x "${JAVA_HOME}/bin/java" ]; then
  JAVA_BIN="${JAVA_HOME}/bin/java"
else
  JAVA_BIN="java"
fi

LOG_DIR="./baseLogs/"
DUMP_DIR="./dump/"
GC_LOG="${LOG_DIR}/gc.log"
# 如果无法启动可以在这里app.log 看下JVM无法创建虚拟机的信息
APP_OUT="${LOG_DIR}/app.log"
START_LOG="${LOG_DIR}/startRecord.log"

HEAP_OPTS="-Xms4g -Xmx8g"
GC_OPTS="-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC"
ERR_OPTS="" # "-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${DUMP_DIR} -XX:ErrorFile=${DUMP_DIR}/hs_err_pid%p.log -XX:+CreateMinidumpOnCrash"
SYS_PROPS="-Dspring.profiles.active=dev -Dserver.port=9000"

START_TIMEOUT=20
STOP_TIMEOUT=20

mkdir -p "${LOG_DIR}" "${DUMP_DIR}"

if [ ! -f "${JAR_PATH}" ]; then
  echo "[$(date +'%F %T')] JAR 不存在: ${JAR_PATH}" | tee -a "${START_LOG}"
  exit 1
fi

pids=$(pgrep -f "${RUN_TAG}" || true)
if [ -n "${pids}" ]; then
  echo "[$(date +'%F %T')] 正在停止进程: ${pids}" | tee -a "${START_LOG}"
  kill ${pids} || true
  for i in $(seq 1 ${STOP_TIMEOUT}); do
    sleep 1
    still=$(pgrep -f "${RUN_TAG}" || true)
    [ -z "${still}" ] && break
  done
  still=$(pgrep -f "${RUN_TAG}" || true)
  if [ -n "${still}" ]; then
    echo "[$(date +'%F %T')] 发送 KILL: ${still}" | tee -a "${START_LOG}"
    kill -9 ${still} || true
  fi
else
  echo "[$(date +'%F %T')] 无需停止,未发现旧进程" | tee -a "${START_LOG}"
fi

echo "[$(date +'%F %T')] 开始启动 ${APP_NAME}" | tee -a "${START_LOG}"

nohup ${JAVA_BIN:-java} \
  ${HEAP_OPTS} ${GC_OPTS} ${ERR_OPTS} ${SYS_PROPS} \
  -jar "${JAR_PATH}" \
  >> "${APP_OUT}" 2>&1 &

new_pid=$!
echo "[$(date +'%F %T')] 启动中,PID=${new_pid}" | tee -a "${START_LOG}"

for i in $(seq 1 ${START_TIMEOUT}); do
  if ps -p "${new_pid}" > /dev/null 2>&1; then
    echo "[$(date +'%F %T')] 启动成功 PID=${new_pid}" | tee -a "${START_LOG}"
    exit 0
  fi
  sleep 1
done

echo "[$(date +'%F %T')] 启动超时,检查日志 ${APP_OUT}" | tee -a "${START_LOG}"
exit 2
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤

免责声明:
本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。