#!/bin/bash
usage() {
echo "使用方法: "
echo " $0 [命令] [选项]"
echo ""
echo "命令: "
echo " start - 启动应用"
echo " stop - 停止应用"
echo " restart - 重启应用"
echo " status - 查看应用状态"
echo ""
echo "选项: "
echo " -n, --name <名称> 应用名称 (默认: your-app-name)"
echo " -j, --jar <路径> JAR包路径 (默认: ./app.jar)"
echo " -p, --port <端口> 应用端口 (默认: 8080)"
echo " -e, --env <环境> 运行环境 (默认: prod)"
echo " --pid <路径> PID文件路径 (默认: ./app.pid)"
echo " --log <路径> 日志文件路径 (默认: ./app.log)"
echo " --jvm <参数> JVM参数 (可选)"
echo " --java <路径> Java路径 (可选,例如: /usr/java/jdk1.8.0_301)"
echo ""
echo "示例: "
echo " $0 start -n myapp -j app.jar --java /usr/java/jdk1.8.0_301"
echo " $0 start --name myapp --jar app.jar --java /path/to/java --jvm '-Xms512m -Xmx1024m'"
}
# 默认值设置
APP_NAME="your-app-name"
JAR_PATH="./app.jar"
PORT="8080"
ENV="prod"
PID_FILE="./app.pid"
LOG_FILE="./app.log"
JAVA_OPTS=""
JAVA_HOME=""
# 验证Java环境
check_java() {
local java_cmd="java"
if [ -n "$JAVA_HOME" ]; then
if [ -x "$JAVA_HOME/bin/java" ]; then
java_cmd="$JAVA_HOME/bin/java"
else
echo "错误: 指定的Java路径无效: $JAVA_HOME"
exit 1
fi
fi
if ! command -v $java_cmd &> /dev/null; then
echo "错误: 未找到java命令"
exit 1
fi
echo "使用Java环境: $($java_cmd -version 2>&1 | head -n 1)"
return 0
}
# 获取进程ID
get_pid() {
if [ -f $PID_FILE ]; then
echo $(cat $PID_FILE)
fi
}
# 检查应用状态
check_status() {
pid=$(get_pid)
if [ -n "$pid" ]; then
if ps -p $pid > /dev/null; then
echo "$APP_NAME 正在运行,PID: $pid"
return 0
fi
fi
echo "$APP_NAME 未运行"
return 1
}
# 启动应用
start() {
echo "正在启动 $APP_NAME..."
# 检查JAR包是否存在
if [ ! -f "$JAR_PATH" ]; then
echo "错误: JAR包不存在 ($JAR_PATH)"
return 1
fi
# 检查是否已经运行
if check_status > /dev/null; then
echo "$APP_NAME 已经在运行中"
return 1
fi
# 验证Java环境
check_java
# 创建日志目录
LOG_DIR=$(dirname "$LOG_FILE")
mkdir -p "$LOG_DIR"
# 构建Java命令
local java_cmd="java"
if [ -n "$JAVA_HOME" ]; then
java_cmd="$JAVA_HOME/bin/java"
fi
# 启动应用
nohup $java_cmd -jar \
-Dserver.port=$PORT \
-Dspring.profiles.active=$ENV \
-Dfile.encoding=UTF-8 \
$JAVA_OPTS \
$JAR_PATH > $LOG_FILE 2>&1 &
# 保存PID
echo $! > $PID_FILE
# 等待应用启动
sleep 3
if check_status > /dev/null; then
echo "应用启动成功!"
echo "应用名称: $APP_NAME"
echo "JAR路径: $JAR_PATH"
echo "端口: $PORT"
echo "环境: $ENV"
echo "PID文件: $PID_FILE"
echo "日志文件: $LOG_FILE"
echo "JVM参数: $JAVA_OPTS"
else
echo "应用启动失败,请检查日志文件: $LOG_FILE"
rm -f $PID_FILE
return 1
fi
}
# 停止应用
stop() {
echo "正在停止 $APP_NAME..."
pid=$(get_pid)
if [ -z "$pid" ]; then
echo "$APP_NAME 未运行"
return 0
fi
# 尝试优雅停止
kill $pid
for i in {1..30}; do
if ! ps -p $pid > /dev/null; then
rm -f $PID_FILE
echo "$APP_NAME 已停止"
return 0
fi
sleep 1
done
# 强制停止
echo "强制停止 $APP_NAME..."
kill -9 $pid
rm -f $PID_FILE
echo "$APP_NAME 已强制停止"
}
# 重启应用
restart() {
stop
sleep 2
start
}
# 解析命令行参数
COMMAND=""
while [[ $# -gt 0 ]]; do
case $1 in
start|stop|restart|status)
COMMAND=$1
shift
;;
-n|--name)
APP_NAME="$2"
shift 2
;;
-j|--jar)
JAR_PATH="$2"
shift 2
;;
-p|--port)
PORT="$2"
shift 2
;;
-e|--env)
ENV="$2"
shift 2
;;
--pid)
PID_FILE="$2"
shift 2
;;
--log)
LOG_FILE="$2"
shift 2
;;
--jvm)
JAVA_OPTS="$2"
shift 2
;;
--java)
JAVA_HOME="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "错误: 未知参数 $1"
usage
exit 1
;;
esac
done
# 检查必需的命令
if [ -z "$COMMAND" ]; then
echo "错误: 必须指定一个命令 (start|stop|restart|status)"
usage
exit 1
fi
# 执行命令
case $COMMAND in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
check_status
;;
esac
使用示例:
- 使用指定的Java环境启动:
./deploy.sh start \
--name myapp \
--jar app.jar \
--java /usr/java/jdk1.8.0_301 \
--port 8080
- 同时指定Java环境和JVM参数:
./deploy.sh start \
--name myapp \
--jar app.jar \
--java /usr/java/jdk1.8.0_301 \
--jvm '-Xms512m -Xmx1024m -XX:+UseG1GC'
- 使用系统默认Java环境:
./deploy.sh start --name myapp --jar app.jar
注意事项:
- 指定的Java路径必须是有效的JDK或JRE安装目录
- 如果不指定
--java
参数,将使用系统默认的Java环境 - 脚本会在启动前验证Java环境的可用性
- 如果指定的Java路径无效,脚本会报错并退出
- 可以通过
--jvm
参数额外指定JVM运行参数