Java 部署脚本,支持回滚

Java 部署脚本
Java Sprintboot jar 项目启动、停止脚本:https://www.cnblogs.com/vipsoft/p/15952112.html
SpringBoot 不同的环境,打不同的包名: https://www.cnblogs.com/vipsoft/p/18577679

#!/bin/bash

# 使用说明
usage() {
    echo "使用说明:"
    echo "  ./deploy.sh deploy <新jar包>      # 部署新版本,默认使用文件里写好的"
    echo "  ./deploy.sh rollback <版本号>     # 回滚到指定版本(格式: 20241229_1430),默认使用文件里写好的"
    echo "  ./deploy.sh stop                  # 停止应用"
    echo "  ./deploy.sh start                 # 启动应用"
    echo "  ./deploy.sh restart               # 重启应用"
    echo "  ./deploy.sh status                # 查看状态"
    echo "  ./deploy.sh logs [行数]           # 查看日志(默认50行),默认为 tail -f"
    echo "  ./deploy.sh backup                # 备份当前版本"
    echo ""
    echo "示例:"
    echo "  ./deploy.sh deploy app-1.27.1.jar1229"
    echo "  ./deploy.sh rollback vipsoft-gateway-1.0.1.jar1229"
}


# 应用配置
RUN_JAR_NAME="vipsoft-gateway-1.0.1.jar"
NEW_JAR_NAME="vipsoft-gateway-1.0.2.jar"
BACK_JAR_NAME="vipsoft-gateway-1.0.1.jar1229"

JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
SPRING_OPTS="--spring.profiles.active=test"
LOG_DIR="./logs"
PID_FILE="./app.pid"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 创建日志目录
mkdir -p $LOG_DIR

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}


# 部署新版本
deploy_jar() {
    local new_jar="$1"
    if [ ! -z "$1" ]; then
        NEW_JAR_NAME=$new_jar
    fi

    if [ ! -f "$NEW_JAR_NAME" ]; then
        print_error "部署版本不存在: ${NEW_JAR_NAME}"
        exit 1
    fi
    print_info "部署: ${NEW_JAR_NAME}"
 
    # 停止应用
    stop
    
    # 替换jar包
    if [ -f "$RUN_JAR_NAME" ]; then
        #mv "$RUN_JAR_NAME" "${RUN_JAR_NAME}.${TIMESTAMP}"
        mv "$RUN_JAR_NAME" "${BACK_JAR_NAME}"        
        print_info "备份: ${RUN_JAR_NAME} => ${BACK_JAR_NAME}"
    fi
    
    #mv "$new_jar" "$RUN_JAR_NAME"

    RUN_JAR_NAME=$NEW_JAR_NAME

    # 启动应用
    start
}


# 回滚到指定版本
rollback_version() {
    local backup_jar="$1" 
    if [ ! -z "$1" ]; then
        BACK_JAR_NAME=$backup_jar
    fi
    if [ ! -f "$BACK_JAR_NAME" ]; then
        print_error "备份版本不存在: ${BACK_JAR_NAME}"
        echo "可用的备份版本:"
        ls -l ${NEW_JAR_NAME}.* 2>/dev/null || echo "暂无备份"
        exit 1
    fi
 
    # 停止应用
    stop
     
    if [ -f "$RUN_JAR_NAME" ]; then
        #mv "$RUN_JAR_NAME" "${RUN_JAR_NAME}.${TIMESTAMP}"
        mv "$RUN_JAR_NAME" "${BACK_JAR_NAME}"        
        print_info "备份: ${RUN_JAR_NAME}"
    fi
 
    mv "$BACK_JAR_NAME" "$RUN_JAR_NAME"

    print_info "回滚到版本: ${BACK_JAR_NAME}"
    #deploy_jar "$backup_jar"

    #RUN_JAR_NAME=$NEW_JAR_NAME

    # 启动应用
    start
}

# 备份当前jar包
backup_current_jar() {
    if [ -f "$JAR_NAME" ]; then
        # 创建备份目录
        mkdir -p $BACKUP_DIR
        
        local backup_name="${JAR_NAME}.${TIMESTAMP}"
        print_info "备份当前版本: $backup_name"
        cp "$JAR_NAME" "$BACKUP_DIR/$backup_name"
        
        # 清理旧备份,保留最近5个
        (cd $BACKUP_DIR && ls -t ${JAR_NAME}.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true)
    else
        print_warn "当前jar包不存在,无需备份"
    fi
}

start() {
    if [ -f $PID_FILE ] && kill -0 $(cat $PID_FILE) 2>/dev/null; then
        echo "${RUN_JAR_NAME} 应用已经在运行,PID: $(cat $PID_FILE)"
        exit 1
    fi
    
    echo "正在启动应用 ${RUN_JAR_NAME}..."
    nohup java $JAVA_OPTS -jar $RUN_JAR_NAME $SPRING_OPTS > $LOG_DIR/app.out 2>&1 &
    echo $! > $PID_FILE
    echo "应用启动成功 ${RUN_JAR_NAME},PID: $(cat $PID_FILE)"
    show_logs
}

stop() {
    if [ ! -f $PID_FILE ]; then
        echo "PID文件不存在,应用可能未运行"
        return 1
    fi
    
    PID=$(cat $PID_FILE)
    echo "正在停止应用 ${RUN_JAR_NAME},PID: ${PID}"
    
    # 优雅停止
    kill $PID 2>/dev/null
    
    # 等待最多30秒
    for i in {1..30}; do
        if kill -0 $PID 2>/dev/null; then
            sleep 1
        else
            echo "应用已停止 ${RUN_JAR_NAME}"
            rm -f $PID_FILE
            return 0
        fi
    done
    
    # 强制停止
    echo "强制停止应用 ${RUN_JAR_NAME}..."
    kill -9 $PID 2>/dev/null
    rm -f $PID_FILE
    echo "应用已强制停止 ${RUN_JAR_NAME}"
}

restart() {
    stop
    sleep 2
    start
}

status() {
    if [ -f $PID_FILE ] && kill -0 $(cat $PID_FILE) 2>/dev/null; then
        echo "应用正在运行,PID: $(cat $PID_FILE)"
        ps -p $(cat $PID_FILE) -o pid,cmd,lstart
    else
        echo "应用未运行"
    fi
}

# 查看日志
show_logs() {
    local logFile=$LOG_DIR/debug.log
    if [ -z "$1" ]; then
        tail -f $logFile
    elif [ -f "$logFile" ]; then
        local lines=${1:-50}
        tail -n $lines $logFile
    else
        print_warn "日志文件不存在:${logFile}"
    fi
}

# 主函数
main() {
    case "$1" in
        deploy)
            # if [ -z "$2" ]; then
            #     print_error "请指定要部署的jar包"
            #     usage
            #     exit 1
            # fi
            deploy_jar "$2"
            ;;
        rollback)
            # if [ -z "$2" ]; then
            #     print_error "请指定要回滚的版本号"
            #     usage
            #     exit 1
            # fi
            rollback_version "$2"
            ;;
        start)
            start
            ;;
        stop)
            stop
            ;;
        restart)
            restart
            ;;
        status)
            status
            ;;

        logs)
            show_logs "$2"
            ;;
        *)
            echo "使用说明: $0 {start|stop|restart|status}"
            exit 1
            ;;
    esac
}    

# 脚本入口
if [ $# -eq 0 ]; then
    usage
    exit 1
fi

main "$@"
posted @ 2025-12-29 16:09  VipSoft  阅读(1)  评论(0)    收藏  举报