四零语境后端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

273 lines
7.3 KiB

#!/bin/bash
# ========================================
# Java应用启动/重启脚本
# 使用方法: ./restart-java-app.sh
# ========================================
# ========================================
# 配置参数 - 请根据实际情况修改
# ========================================
JAR_NAME="" # 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() {
# 如果JAR_NAME为空,自动检测当前目录下的JAR文件
if [ -z "$JAR_NAME" ]; then
local jar_files=(*.jar)
local jar_count=${#jar_files[@]}
# 检查是否存在JAR文件
if [ ! -f "${jar_files[0]}" ]; then
print_message $RED "错误: 当前目录下没有找到JAR文件!"
print_message $YELLOW "请将JAR文件放在脚本同一目录下,或在脚本中指定JAR_NAME"
exit 1
fi
# 如果只有一个JAR文件,自动使用它
if [ $jar_count -eq 1 ]; then
JAR_NAME="${jar_files[0]}"
print_message $BLUE "自动检测到JAR文件: $JAR_NAME"
else
print_message $RED "错误: 当前目录下有多个JAR文件,请在脚本中指定JAR_NAME:"
for jar in "${jar_files[@]}"; do
print_message $YELLOW " - $jar"
done
exit 1
fi
else
# 检查指定的JAR文件是否存在
if [ ! -f "$JAR_NAME" ]; then
print_message $RED "错误: JAR文件 '$JAR_NAME' 不存在!"
print_message $YELLOW "请检查JAR_NAME配置是否正确,或确保JAR文件在当前目录下"
exit 1
fi
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文件,可以将JAR_NAME留空实现自动检测"
}
# ========================================
# 主程序
# ========================================
# 检查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