From 711d63ec0c56f3f860256a3d0b6165af67868ed5 Mon Sep 17 00:00:00 2001 From: huliyong <2783385703@qq.com> Date: Fri, 26 Sep 2025 23:10:38 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0Java=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=AE=A1=E7=90=86=E8=84=9A=E6=9C=AC=E5=8F=8A=E5=85=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加了restart-java-app.sh脚本用于管理Java应用的启动、停止和重启 同时添加了详细的README文档说明脚本功能和使用方法 --- README-restart-script.md | 175 +++++++++++++++++++++++++++++++++ restart-java-app.sh | 247 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 422 insertions(+) create mode 100644 README-restart-script.md create mode 100644 restart-java-app.sh diff --git a/README-restart-script.md b/README-restart-script.md new file mode 100644 index 0000000..aa4e85e --- /dev/null +++ b/README-restart-script.md @@ -0,0 +1,175 @@ +# Java应用启动/重启脚本使用说明 + +## 概述 + +`restart-java-app.sh` 是一个用于在Linux系统下管理Java JAR包应用的Shell脚本。它可以自动检测应用是否运行,并提供启动、停止、重启等功能。 + +## 功能特性 + +- ✅ 自动检测应用运行状态 +- ✅ 优雅停止应用(先发送TERM信号,超时后强制停止) +- ✅ 智能端口检测,避免端口冲突 +- ✅ PID文件管理,确保进程跟踪准确 +- ✅ 彩色日志输出,便于查看状态 +- ✅ 详细的错误处理和状态反馈 +- ✅ 支持多种命令选项 + +## 配置参数 + +在使用脚本前,需要修改脚本开头的配置参数: + +```bash +# ======================================== +# 配置参数 - 请根据实际情况修改 +# ======================================== +JAR_NAME="your-app.jar" # JAR包名称 +PORT=8080 # 应用端口号 +``` + +### 主要配置项 + +| 参数 | 说明 | 示例 | +|------|------|------| +| `JAR_NAME` | JAR包文件名 | `"my-spring-boot-app.jar"` | +| `PORT` | 应用监听端口 | `8080` | + +### 可选配置项 + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `JAVA_OPTS` | JVM启动参数 | `"-Xms512m -Xmx1024m"` | +| `LOG_FILE` | 日志文件名 | `"app.log"` | +| `PID_FILE` | PID文件名 | `"app.pid"` | + +## 使用方法 + +### 1. 设置执行权限 + +```bash +chmod +x restart-java-app.sh +``` + +### 2. 基本用法 + +```bash +# 重启应用(默认操作) +./restart-java-app.sh + +# 或者明确指定重启 +./restart-java-app.sh restart +``` + +### 3. 其他命令 + +```bash +# 启动应用 +./restart-java-app.sh start + +# 停止应用 +./restart-java-app.sh stop + +# 查看应用状态 +./restart-java-app.sh status + +# 显示帮助信息 +./restart-java-app.sh help +``` + +## 命令详解 + +### start - 启动应用 +- 检查JAR文件是否存在 +- 检查端口是否被占用 +- 启动Java应用 +- 等待应用完全启动 +- 验证端口监听状态 + +### stop - 停止应用 +- 查找应用进程PID +- 发送TERM信号优雅停止 +- 等待最多30秒 +- 超时后强制停止(KILL信号) +- 清理PID文件 + +### restart - 重启应用 +- 先执行stop操作 +- 等待2秒 +- 再执行start操作 + +### status - 查看状态 +- 显示应用运行状态 +- 显示进程PID +- 显示端口监听状态 + +## 输出说明 + +脚本使用彩色输出来区分不同类型的消息: + +- 🔴 **红色**: 错误信息 +- 🟢 **绿色**: 成功信息 +- 🟡 **黄色**: 警告信息 +- 🔵 **蓝色**: 操作信息 + +## 文件说明 + +脚本运行时会创建以下文件: + +- `app.log`: 应用运行日志 +- `app.pid`: 应用进程PID文件 + +## 常见问题 + +### Q: 提示"JAR文件不存在" +**A**: 检查`JAR_NAME`配置是否正确,确保JAR文件在脚本同一目录下。 + +### Q: 提示"端口已被占用" +**A**: 检查是否有其他应用占用了配置的端口,或修改`PORT`配置。 + +### Q: 应用启动失败 +**A**: 查看`app.log`日志文件,检查具体错误原因。 + +### Q: 无法停止应用 +**A**: 脚本会先尝试优雅停止,30秒后自动强制停止。 + +## 系统要求 + +- Linux操作系统 +- Bash Shell +- Java运行环境 +- 网络工具(netstat、ss或lsof中的任意一个) + +## 注意事项 + +1. 确保脚本有执行权限 +2. 确保Java环境已正确安装 +3. 确保JAR文件路径正确 +4. 建议在生产环境使用前先在测试环境验证 +5. 定期检查日志文件大小,避免占用过多磁盘空间 + +## 示例 + +假设你有一个名为`my-app.jar`的Spring Boot应用,需要在8080端口运行: + +1. 修改脚本配置: +```bash +JAR_NAME="my-app.jar" +PORT=8080 +``` + +2. 启动应用: +```bash +./restart-java-app.sh start +``` + +3. 查看状态: +```bash +./restart-java-app.sh status +``` + +输出示例: +``` +[2024-01-15 10:30:15] 应用正在运行 +[2024-01-15 10:30:15] PID: 12345 +[2024-01-15 10:30:15] 端口: 8080 +[2024-01-15 10:30:15] 端口状态: 正在监听 +``` \ No newline at end of file diff --git a/restart-java-app.sh b/restart-java-app.sh new file mode 100644 index 0000000..a822616 --- /dev/null +++ b/restart-java-app.sh @@ -0,0 +1,247 @@ +#!/bin/bash + +# ======================================== +# Java应用启动/重启脚本 +# 使用方法: ./restart-java-app.sh +# ======================================== + +# ======================================== +# 配置参数 - 请根据实际情况修改 +# ======================================== +JAR_NAME="your-app.jar" # JAR包名称 +PORT=8080 # 应用端口号 + +# ======================================== +# 其他配置(一般不需要修改) +# ======================================== +JAVA_OPTS="-Xms512m -Xmx1024m" # JVM参数 +LOG_FILE="app.log" # 日志文件名 +PID_FILE="app.pid" # PID文件名 + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# ======================================== +# 函数定义 +# ======================================== + +# 打印带颜色的消息 +print_message() { + local color=$1 + local message=$2 + echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] ${message}${NC}" +} + +# 检查JAR文件是否存在 +check_jar_exists() { + if [ ! -f "$JAR_NAME" ]; then + print_message $RED "错误: JAR文件 '$JAR_NAME' 不存在!" + print_message $YELLOW "请检查JAR_NAME配置是否正确,或确保JAR文件在当前目录下" + exit 1 + fi +} + +# 检查端口是否被占用 +check_port() { + local port=$1 + if command -v netstat >/dev/null 2>&1; then + netstat -tlnp 2>/dev/null | grep ":$port " >/dev/null + elif command -v ss >/dev/null 2>&1; then + ss -tlnp | grep ":$port " >/dev/null + else + # 如果没有netstat和ss,尝试使用lsof + if command -v lsof >/dev/null 2>&1; then + lsof -i :$port >/dev/null 2>&1 + else + return 1 + fi + fi +} + +# 获取运行中的应用PID +get_app_pid() { + if [ -f "$PID_FILE" ]; then + local pid=$(cat "$PID_FILE") + # 检查进程是否真的在运行 + if ps -p $pid > /dev/null 2>&1; then + echo $pid + else + # PID文件存在但进程不存在,删除PID文件 + rm -f "$PID_FILE" + echo "" + fi + else + # 通过进程名查找 + pgrep -f "$JAR_NAME" | head -1 + fi +} + +# 停止应用 +stop_app() { + local pid=$(get_app_pid) + + if [ -z "$pid" ]; then + print_message $YELLOW "应用未运行" + return 0 + fi + + print_message $YELLOW "正在停止应用 (PID: $pid)..." + + # 优雅停止 + kill $pid + + # 等待进程停止 + local count=0 + while [ $count -lt 30 ]; do + if ! ps -p $pid > /dev/null 2>&1; then + print_message $GREEN "应用已成功停止" + rm -f "$PID_FILE" + return 0 + fi + sleep 1 + count=$((count + 1)) + done + + # 如果优雅停止失败,强制停止 + print_message $YELLOW "优雅停止超时,强制停止应用..." + kill -9 $pid 2>/dev/null + + sleep 2 + if ! ps -p $pid > /dev/null 2>&1; then + print_message $GREEN "应用已强制停止" + rm -f "$PID_FILE" + return 0 + else + print_message $RED "停止应用失败" + return 1 + fi +} + +# 启动应用 +start_app() { + print_message $BLUE "正在启动应用..." + + # 检查端口是否被占用 + if check_port $PORT; then + print_message $RED "端口 $PORT 已被占用,请检查是否有其他应用在使用该端口" + return 1 + fi + + # 启动应用 + nohup java $JAVA_OPTS -jar "$JAR_NAME" --server.port=$PORT > "$LOG_FILE" 2>&1 & + local pid=$! + + # 保存PID + echo $pid > "$PID_FILE" + + # 等待应用启动 + print_message $BLUE "等待应用启动..." + sleep 3 + + # 检查进程是否还在运行 + if ps -p $pid > /dev/null 2>&1; then + # 检查端口是否监听 + local count=0 + while [ $count -lt 30 ]; do + if check_port $PORT; then + print_message $GREEN "应用启动成功!" + print_message $GREEN "PID: $pid" + print_message $GREEN "端口: $PORT" + print_message $GREEN "日志文件: $LOG_FILE" + return 0 + fi + sleep 1 + count=$((count + 1)) + done + + print_message $YELLOW "应用进程已启动,但端口 $PORT 未监听,请检查日志文件: $LOG_FILE" + return 1 + else + print_message $RED "应用启动失败,请检查日志文件: $LOG_FILE" + rm -f "$PID_FILE" + return 1 + fi +} + +# 显示应用状态 +show_status() { + local pid=$(get_app_pid) + + if [ -n "$pid" ]; then + print_message $GREEN "应用正在运行" + print_message $GREEN "PID: $pid" + print_message $GREEN "端口: $PORT" + + if check_port $PORT; then + print_message $GREEN "端口状态: 正在监听" + else + print_message $YELLOW "端口状态: 未监听" + fi + else + print_message $YELLOW "应用未运行" + fi +} + +# 显示帮助信息 +show_help() { + echo "Java应用管理脚本" + echo "" + echo "使用方法:" + echo " $0 [选项]" + echo "" + echo "选项:" + echo " start 启动应用" + echo " stop 停止应用" + echo " restart 重启应用" + echo " status 显示应用状态" + echo " help 显示帮助信息" + echo "" + echo "配置:" + echo " JAR包名称: $JAR_NAME" + echo " 端口号: $PORT" + echo "" + echo "注意: 请确保在脚本开头正确配置 JAR_NAME 和 PORT 参数" +} + +# ======================================== +# 主程序 +# ======================================== + +# 检查JAR文件是否存在 +check_jar_exists + +# 处理命令行参数 +case "${1:-restart}" in + "start") + start_app + ;; + "stop") + stop_app + ;; + "restart") + print_message $BLUE "重启应用..." + stop_app + if [ $? -eq 0 ]; then + sleep 2 + start_app + else + print_message $RED "停止应用失败,取消重启" + exit 1 + fi + ;; + "status") + show_status + ;; + "help"|"-h"|"--help") + show_help + ;; + *) + print_message $RED "未知选项: $1" + show_help + exit 1 + ;; +esac \ No newline at end of file