首页 热门资讯文章正文

SpringBoot应用部署神器:可视化服务管理脚本让运维更轻松

热门资讯 2025年09月07日 12:00 2 admin

在SpringBoot应用的生产环境部署中,传统的手动启停服务方式不仅效率低下,还容易出错。

SpringBoot应用部署神器:可视化服务管理脚本让运维更轻松

今天分享一个功能强大的可视化服务管理脚本,让SpringBoot应用的部署和运维变得简单高效。

痛点分析:传统部署方式的困扰

相信很多开发者都遇到过这些问题:

  • 操作繁琐:每次部署都要手动执行一堆命令
  • 状态不明:不知道服务是否真正启动成功
  • 日志分散:查看日志需要记住各种路径
  • 回滚困难:出问题时手忙脚乱找备份
  • 多服务管理:微服务架构下管理复杂度倍增

这些问题不仅影响开发效率,还增加了生产环境的风险。

解决方案:可视化服务管理器

为了解决这些痛点,我开发了一套完整的SpringBoot服务管理解决方案,核心特性包括:

可视化操作界面

告别枯燥的命令行操作,采用彩色终端界面:

#################### SpringBoot服务管理器 ####################当前时间: 2024-01-15 14:30:25配置文件: /path/to/services.conf日志目录: /path/to/logs================== 服务列表 ==================序号 服务名称              端口       状态-----------------------------------------------1   user-service         8080      运行中 (PID: 1234, Port: 8080)2   order-service        8081      已停止3   payment-service      8082      启动中 (PID: 5678)===============================================

界面直观清晰,服务状态一目了然,支持实时状态更新和彩色状态标识。

智能服务管理

1. 配置驱动的服务管理

通过简单的配置文件管理所有服务:

# services.conf 配置格式# 服务名称|JAR路径|端口|环境|JVM参数user-service|/opt/apps/user-service.jar|8080|prod|-Xms512m -Xmx1024morder-service|/opt/apps/order-service.jar|8081|prod|-Xms256m -Xmx512m

这种配置方式的优势:

  • 统一管理:所有服务配置集中管理
  • 灵活配置:支持不同JVM参数和环境配置
  • 易于维护:修改配置无需改动脚本

2. 智能启停机制

优雅启动流程:

检查JAR文件 → 验证端口可用性 → 构建启动命令 → 后台启动服务 → 健康检查 → 状态确认

安全停止流程:

发送TERM信号 → 等待优雅停止 → 超时强制终止 → 状态确认

这种机制确保服务启停的可靠性,避免了常见的端口占用和进程残留问题。

全方位监控功能

1. 实时状态监控

==================== 服务详细信息 ====================服务名称: user-service运行状态: 运行中 (PID: 1234, Port: 8080)内存使用: 345.6 MBCPU使用: 12.5%启动时间: Dec 15 14:30日志大小: 25.3M======================================================

2. 系统资源监控

==================== 系统资源信息 ====================CPU使用率: 15.2%内存使用: 4.2G / 8.0G磁盘使用: 25G / 50G (52%)Java进程: 3个运行中======================================================	

这些监控信息帮助运维人员及时发现性能瓶颈和资源问题。

智能日志管理

支持多种日志查看方式:

  • 实时跟踪:tail -f 实时查看最新日志
  • 历史查看:查看指定行数的历史日志
  • 全文浏览:使用less命令浏览完整日志
  • 日志轮转:自动管理日志文件大小

日志管理界面:

请选择查看方式:1) 查看最后50行2) 查看最后100行3) 实时跟踪日志4) 查看全部日志

批量操作支持

微服务架构下,批量操作必不可少:

==================== 批量操作菜单 ====================1) 启动所有服务2) 停止所有服务  3) 重启所有服务4) 查看所有服务状态======================================================

批量操作特别适用于: 系统重启后的服务恢复 版本发布时的服务更新 故障处理时的快速响应

自动化部署解决方案

除了服务管理,还提供了完整的自动化部署脚本:

一键部署流程

./deploy.sh deploy app-1.0.0.jar

部署流程包括:

  • 1. 环境检查:验证部署环境和依赖
  • 2. 版本备份:自动备份当前运行版本
  • 3. 服务停止:优雅停止当前服务
  • 4. 文件部署:复制新版本到部署目录
  • 5. 服务启动:启动新版本服务
  • 6. 健康检查:验证服务是否正常运行
  • 7. 清理备份:保留最近5个版本备份

安全回滚机制

当部署出现问题时:

./deploy.sh rollback

回滚流程:

  • 自动查找最新备份版本
  • 停止问题版本服务
  • 恢复备份文件
  • 重启服务并验证

这种设计确保了部署过程的安全性,即使出现问题也能快速恢复。

实战应用场景

场景1:微服务集群管理

某电商公司有用户服务、订单服务、支付服务等10个微服务:

传统方式

  • 需要登录到每台服务器
  • 手动执行启停命令
  • 分别查看各服务日志
  • 耗时30分钟+

使用脚本后

  • 一个界面管理所有服务
  • 批量操作3分钟完成
  • 状态监控一目了然
  • 效率提升10倍

场景2:版本发布管理

发布前

# 查看当前所有服务状态选择批量操作 → 查看所有服务状态

发布过程

# 逐个服务更新./deploy.sh deploy user-service-v2.0.jar./deploy.sh deploy order-service-v2.0.jar

发布验证

# 健康检查和监控./deploy.sh health

场景3:故障应急处理

当生产环境出现问题:

  • 1. 快速定位:通过状态监控快速识别问题服务
  • 2. 日志分析:实时查看相关服务日志
  • 3. 紧急处理:重启问题服务或快速回滚
  • 4. 影响评估:查看系统资源使用情况

最佳实践建议

1. 配置管理

  • 使用版本控制管理配置文件
  • 不同环境使用不同的配置
  • 定期备份配置文件

2. 监控告警

  • 配合监控系统使用
  • 设置关键指标告警
  • 建立故障处理流程

3. 安全考虑

  • 限制脚本执行权限
  • 使用非root用户运行
  • 定期清理敏感日志

4. 性能优化

  • 合理配置JVM参数
  • 监控服务资源使用
  • 定期优化配置参数

总结

这套基于SHELL的SpringBoot服务管理解决方案通过可视化界面、智能管理机制、资源监控和自动化部署,可以极大提供服务管理效率。

它不仅大大提升了运维效率,还降低了操作风险,特别适合单机多服务和小规模微服务架构的部署场景。

如果你也在为SpringBoot应用的部署和管理而烦恼,不妨试试这套解决方案。相信它会让你的运维工作变得更加轻松高效!

脚本附录

springboot-service-manager

#!/bin/bash# SpringBoot服务管理脚本 - 可视化版本# 支持多个服务的启动、停止、重启、状态查看等功能# 配置目录SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"CONFIG_FILE="$SCRIPT_DIR/services.conf"LOG_DIR="$SCRIPT_DIR/logs"# 创建必要目录mkdir -p "$LOG_DIR"# 颜色定义RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'PURPLE='\033[0;35m'CYAN='\033[0;36m'WHITE='\033[1;37m'NC='\033[0m' # No Color# 加载服务配置load_services() {    if [[ ! -f "$CONFIG_FILE" ]]; then        echo -e "${RED}配置文件不存在: $CONFIG_FILE${NC}"        echo "请先创建配置文件,参考 services.conf.example"        exit 1    fi        # 清空服务数组    unset SERVICE_NAMES    unset SERVICE_PATHS    unset SERVICE_PORTS    unset SERVICE_PROFILES    unset SERVICE_JVM_OPTS        declare -g -a SERVICE_NAMES=()    declare -g -a SERVICE_PATHS=()    declare -g -a SERVICE_PORTS=()    declare -g -a SERVICE_PROFILES=()    declare -g -a SERVICE_JVM_OPTS=()        # 读取配置文件    while IFS='|' read -r name path port profile jvm_opts; do        # 跳过注释和空行        [[ $name =~ ^#.*$ ]] && continue        [[ -z "$name" ]] && continue                SERVICE_NAMES+=("$name")        SERVICE_PATHS+=("$path")        SERVICE_PORTS+=("$port")        SERVICE_PROFILES+=("$profile")        SERVICE_JVM_OPTS+=("$jvm_opts")    done < "$CONFIG_FILE"}# 获取服务PIDget_service_pid() {    local service_name=$1    local port=$2        # 先通过端口查找    if [[ -n "$port" ]]; then        pid=$(lsof -ti:$port 2>/dev/null)        if [[ -n "$pid" ]]; then            echo $pid            return        fi    fi        # 通过jar文件名查找    pid=$(ps aux | grep java | grep -v grep | grep "$service_name" | awk '{print $2}')    echo $pid}# 检查服务状态check_service_status() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}    local port=${SERVICE_PORTS[$index]}        local pid=$(get_service_pid "$service_name" "$port")        if [[ -n "$pid" ]]; then        # 检查端口是否可访问        if [[ -n "$port" ]] && nc -z localhost $port 2>/dev/null; then            echo -e "${GREEN}运行中${NC} (PID: $pid, Port: $port)"        else            echo -e "${YELLOW}启动中${NC} (PID: $pid)"        fi        return 0    else        echo -e "${RED}已停止${NC}"        return 1    fi}# 启动服务start_service() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}    local jar_path=${SERVICE_PATHS[$index]}    local port=${SERVICE_PORTS[$index]}    local profile=${SERVICE_PROFILES[$index]}    local jvm_opts=${SERVICE_JVM_OPTS[$index]}        echo -e "${BLUE}正在启动服务: $service_name${NC}"        # 检查jar文件是否存在    if [[ ! -f "$jar_path" ]]; then        echo -e "${RED}错误: JAR文件不存在 - $jar_path${NC}"        return 1    fi        # 检查服务是否已经运行    local pid=$(get_service_pid "$service_name" "$port")    if [[ -n "$pid" ]]; then        echo -e "${YELLOW}服务已经在运行中 (PID: $pid)${NC}"        return 0    fi        # 构建启动命令    local cmd="java"    [[ -n "$jvm_opts" ]] && cmd="$cmd $jvm_opts"    [[ -n "$profile" ]] && cmd="$cmd -Dspring.profiles.active=$profile"    cmd="$cmd -jar $jar_path"        # 启动服务    local log_file="$LOG_DIR/${service_name}.log"    nohup $cmd > "$log_file" 2>&1 &    local new_pid=$!        echo "启动命令: $cmd" >> "$log_file"    echo "启动时间: $(date)" >> "$log_file"    echo "进程PID: $new_pid" >> "$log_file"    echo "----------------------------------------" >> "$log_file"        # 等待服务启动    echo -n "等待服务启动"    for i in {1..30}; do        sleep 1        echo -n "."        if [[ -n "$port" ]] && nc -z localhost $port 2>/dev/null; then            echo            echo -e "${GREEN}服务启动成功!${NC} (PID: $new_pid, Port: $port)"            return 0        fi    done        echo    echo -e "${YELLOW}服务已启动,但端口检查超时${NC} (PID: $new_pid)"    echo "请查看日志文件: $log_file"    return 0}# 停止服务stop_service() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}    local port=${SERVICE_PORTS[$index]}        echo -e "${BLUE}正在停止服务: $service_name${NC}"        local pid=$(get_service_pid "$service_name" "$port")    if [[ -z "$pid" ]]; then        echo -e "${YELLOW}服务未运行${NC}"        return 0    fi        # 优雅停止    echo "发送TERM信号..."    kill -TERM $pid        # 等待服务停止    echo -n "等待服务停止"    for i in {1..15}; do        sleep 1        echo -n "."        if ! kill -0 $pid 2>/dev/null; then            echo            echo -e "${GREEN}服务已停止${NC}"            return 0        fi    done        # 强制停止    echo    echo "优雅停止超时,强制停止..."    kill -KILL $pid 2>/dev/null        sleep 2    if ! kill -0 $pid 2>/dev/null; then        echo -e "${GREEN}服务已强制停止${NC}"        return 0    else        echo -e "${RED}服务停止失败${NC}"        return 1    fi}# 重启服务restart_service() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}        echo -e "${BLUE}正在重启服务: $service_name${NC}"        stop_service $index    sleep 2    start_service $index}# 查看服务日志view_service_log() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}    local log_file="$LOG_DIR/${service_name}.log"        if [[ ! -f "$log_file" ]]; then        echo -e "${RED}日志文件不存在: $log_file${NC}"        return 1    fi        echo -e "${BLUE}查看服务日志: $service_name${NC}"    echo "日志文件: $log_file"    echo "----------------------------------------"        # 选择查看方式    echo "请选择查看方式:"    echo "1) 查看最后50行"    echo "2) 查看最后100行"     echo "3) 实时跟踪日志"    echo "4) 查看全部日志"    echo "0) 返回主菜单"        read -p "请输入选择 [1-4]: " log_choice        case $log_choice in        1) tail -50 "$log_file" ;;        2) tail -100 "$log_file" ;;        3) echo "按 Ctrl+C 退出实时跟踪"           sleep 2           tail -f "$log_file" ;;        4) less "$log_file" ;;        0) return ;;        *) echo -e "${RED}无效选择${NC}" ;;    esac}# 显示服务详细信息show_service_detail() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}    local jar_path=${SERVICE_PATHS[$index]}    local port=${SERVICE_PORTS[$index]}    local profile=${SERVICE_PROFILES[$index]}    local jvm_opts=${SERVICE_JVM_OPTS[$index]}        clear    echo -e "${CYAN}==================== 服务详细信息 ====================${NC}"    echo -e "${WHITE}服务名称:${NC} $service_name"    echo -e "${WHITE}JAR路径:${NC} $jar_path"    echo -e "${WHITE}端口号:${NC} ${port:-未配置}"    echo -e "${WHITE}环境配置:${NC} ${profile:-默认}"    echo -e "${WHITE}JVM参数:${NC} ${jvm_opts:-默认}"        local pid=$(get_service_pid "$service_name" "$port")    echo -e "${WHITE}运行状态:${NC} $(check_service_status $index)"        if [[ -n "$pid" ]]; then        echo -e "${WHITE}进程PID:${NC} $pid"        echo -e "${WHITE}内存使用:${NC} $(ps -p $pid -o rss= | awk '{printf "%.1f MB", $1/1024}')"        echo -e "${WHITE}CPU使用:${NC} $(ps -p $pid -o %cpu= | awk '{print $1"%"}')"        echo -e "${WHITE}启动时间:${NC} $(ps -p $pid -o lstart= | awk '{print $1" "$2" "$3" "$4}')"    fi        local log_file="$LOG_DIR/${service_name}.log"    if [[ -f "$log_file" ]]; then        echo -e "${WHITE}日志文件:${NC} $log_file"        echo -e "${WHITE}日志大小:${NC} $(du -h "$log_file" | awk '{print $1}')"    fi        echo -e "${CYAN}======================================================${NC}"    echo    read -p "按回车键返回主菜单..."}# 显示系统资源使用情况show_system_info() {    clear    echo -e "${CYAN}==================== 系统资源信息 ====================${NC}"        # CPU使用率    cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')    echo -e "${WHITE}CPU使用率:${NC} ${cpu_usage}%"        # 内存使用情况    memory_info=$(free -h | grep Mem)    total_mem=$(echo $memory_info | awk '{print $2}')    used_mem=$(echo $memory_info | awk '{print $3}')    echo -e "${WHITE}内存使用:${NC} $used_mem / $total_mem"        # 磁盘使用情况    echo -e "${WHITE}磁盘使用:${NC}"    df -h | grep -E '^/dev/' | awk '{printf "  %s: %s / %s (%s)\n", $1, $3, $2, $5}'        # Java进程信息    echo -e "${WHITE}Java进程:${NC}"    ps aux | grep java | grep -v grep | while read line; do        pid=$(echo $line | awk '{print $2}')        mem=$(echo $line | awk '{print $4}')        cmd=$(echo $line | awk '{for(i=11;i<=NF;i++) printf "%s ", $i; print ""}')        echo "  PID: $pid, MEM: ${mem}%, CMD: ${cmd:0:50}..."    done        echo -e "${CYAN}======================================================${NC}"    echo    read -p "按回车键返回主菜单..."}# 批量操作菜单batch_operations_menu() {    while true; do        clear        echo -e "${PURPLE}==================== 批量操作菜单 ====================${NC}"        echo "1) 启动所有服务"        echo "2) 停止所有服务"        echo "3) 重启所有服务"        echo "4) 查看所有服务状态"        echo "0) 返回主菜单"        echo -e "${PURPLE}======================================================${NC}"                read -p "请输入选择 [0-4]: " batch_choice                case $batch_choice in            1)                echo -e "${BLUE}正在启动所有服务...${NC}"                for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do                    start_service $i                    echo                done                read -p "按回车键继续..."                ;;            2)                echo -e "${BLUE}正在停止所有服务...${NC}"                for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do                    stop_service $i                    echo                done                read -p "按回车键继续..."                ;;            3)                echo -e "${BLUE}正在重启所有服务...${NC}"                for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do                    restart_service $i                    echo                done                read -p "按回车键继续..."                ;;            4)                clear                echo -e "${CYAN}==================== 所有服务状态 ====================${NC}"                printf "%-20s %-10s %-15s\n" "服务名称" "端口" "状态"                echo "------------------------------------------------------"                for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do                    status=$(check_service_status $i)                    printf "%-20s %-10s %s\n" "${SERVICE_NAMES[$i]}" "${SERVICE_PORTS[$i]}" "$status"                done                echo -e "${CYAN}======================================================${NC}"                read -p "按回车键继续..."                ;;            0)                break                ;;            *)                echo -e "${RED}无效选择,请重新输入${NC}"                sleep 1                ;;        esac    done}# 服务管理菜单service_management_menu() {    local index=$1    local service_name=${SERVICE_NAMES[$index]}        while true; do        clear        echo -e "${CYAN}==================== 服务管理: $service_name ====================${NC}"        echo -e "当前状态: $(check_service_status $index)"        echo        echo "1) 启动服务"        echo "2) 停止服务"        echo "3) 重启服务"        echo "4) 查看日志"        echo "5) 服务详情"        echo "0) 返回主菜单"        echo -e "${CYAN}================================================================${NC}"                read -p "请输入选择 [0-5]: " service_choice                case $service_choice in            1)                start_service $index                read -p "按回车键继续..."                ;;            2)                stop_service $index                read -p "按回车键继续..."                ;;            3)                restart_service $index                read -p "按回车键继续..."                ;;            4)                view_service_log $index                ;;            5)                show_service_detail $index                ;;            0)                break                ;;            *)                echo -e "${RED}无效选择,请重新输入${NC}"                sleep 1                ;;        esac    done}# 主菜单main_menu() {    while true; do        clear        echo -e "${GREEN}#################### SpringBoot服务管理器 ####################${NC}"        echo -e "${WHITE}当前时间: $(date '+%Y-%m-%d %H:%M:%S')${NC}"        echo -e "${WHITE}配置文件: $CONFIG_FILE${NC}"        echo -e "${WHITE}日志目录: $LOG_DIR${NC}"        echo                # 显示服务列表和状态        if [[ ${#SERVICE_NAMES[@]} -eq 0 ]]; then            echo -e "${RED}未找到任何服务配置${NC}"        else            echo -e "${CYAN}================== 服务列表 ==================${NC}"            printf "%-3s %-20s %-10s %-15s\n" "序号" "服务名称" "端口" "状态"            echo "-----------------------------------------------"            for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do                status=$(check_service_status $i)                printf "%-3s %-20s %-10s %s\n" "$((i+1))" "${SERVICE_NAMES[$i]}" "${SERVICE_PORTS[$i]}" "$status"            done            echo -e "${CYAN}===============================================${NC}"        fi                echo        echo "操作选项:"        echo "1-${#SERVICE_NAMES[@]}) 管理对应服务"        echo "b) 批量操作"        echo "s) 系统信息"        echo "r) 重新加载配置"        echo "q) 退出程序"        echo -e "${GREEN}#########################################################${NC}"                read -p "请输入选择: " main_choice                case $main_choice in            [1-9]|[1-9][0-9])                index=$((main_choice-1))                if [[ $index -ge 0 && $index -lt ${#SERVICE_NAMES[@]} ]]; then                    service_management_menu $index                else                    echo -e "${RED}无效的服务序号${NC}"                    sleep 1                fi                ;;            b|B)                batch_operations_menu                ;;            s|S)                show_system_info                ;;            r|R)                echo -e "${BLUE}重新加载配置文件...${NC}"                load_services                echo -e "${GREEN}配置加载完成${NC}"                sleep 1                ;;            q|Q)                echo -e "${GREEN}感谢使用SpringBoot服务管理器!${NC}"                exit 0                ;;            *)                echo -e "${RED}无效选择,请重新输入${NC}"                sleep 1                ;;        esac    done}# 检查依赖命令check_dependencies() {    local missing_deps=()        command -v java >/dev/null 2>&1 || missing_deps+=("java")    command -v lsof >/dev/null 2>&1 || missing_deps+=("lsof")    command -v nc >/dev/null 2>&1 || missing_deps+=("netcat")        if [[ ${#missing_deps[@]} -ne 0 ]]; then        echo -e "${RED}错误: 缺少必要的命令工具${NC}"        echo "请安装以下工具: ${missing_deps[*]}"        echo        echo "Ubuntu/Debian: sudo apt-get install openjdk-8-jdk lsof netcat"        echo "CentOS/RHEL: sudo yum install java-1.8.0-openjdk lsof nc"        exit 1    fi}# 主程序入口main() {    # 检查依赖    check_dependencies        # 加载服务配置    load_services        # 显示欢迎信息    clear    echo -e "${GREEN}"    echo "########################################################"    echo "#                                                      #"    echo "#          SpringBoot服务管理器 v1.0                    #"    echo "#                                                      #"    echo "#          支持多服务管理、日志查看、状态监控             #"    echo "#                                                      #"    echo "########################################################"    echo -e "${NC}"        sleep 2        # 启动主菜单    main_menu}# 脚本执行入口if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then    main "$@"fi

services.conf

# SpringBoot服务配置文件# 格式: 服务名称|JAR文件路径|端口号|Profile环境|JVM参数# 示例配置,请根据实际情况修改# 测试服务serveless-core|/opt/apps/serverless-core-1.0.0.jar|8080|prod|-Xms512m -Xmx1024m -XX:+UseG1GC# 注意事项:# 1. 每行一个服务配置# 2. 使用 | 分隔各个字段# 3. JAR文件路径必须是绝对路径# 4. 端口号用于健康检查# 5. Profile环境可以为空,默认使用default# 6. JVM参数可以为空,使用默认配置# 7. 以#开头的行为注释行

deploy.sh

# SpringBoot服务部署脚本# 自动化部署和管理SpringBoot应用#!/bin/bash# 部署配置APP_NAME="serverless-core"APP_VERSION="1.0.0"JAR_NAME="${APP_NAME}-${APP_VERSION}.jar"DEPLOY_DIR="/opt/apps"BACKUP_DIR="/opt/backups"SERVICE_PORT="8080"PROFILE="prod"# JVM参数配置JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"JVM_OPTS="$JVM_OPTS -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"JVM_OPTS="$JVM_OPTS -Xloggc:$DEPLOY_DIR/logs/gc.log -XX:+UseGCLogFileRotation"JVM_OPTS="$JVM_OPTS -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M"# 颜色定义RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'# 创建必要目录setup_directories() {    echo -e "${BLUE}创建部署目录...${NC}"    mkdir -p "$DEPLOY_DIR"    mkdir -p "$DEPLOY_DIR/logs"    mkdir -p "$BACKUP_DIR"    echo -e "${GREEN}目录创建完成${NC}"}# 备份当前版本backup_current_version() {    if [[ -f "$DEPLOY_DIR/$JAR_NAME" ]]; then        echo -e "${BLUE}备份当前版本...${NC}"        local backup_file="$BACKUP_DIR/${JAR_NAME}.$(date +%Y%m%d_%H%M%S).bak"        cp "$DEPLOY_DIR/$JAR_NAME" "$backup_file"        echo -e "${GREEN}备份完成: $backup_file${NC}"    fi}# 部署新版本deploy_new_version() {    local jar_file=$1        if [[ ! -f "$jar_file" ]]; then        echo -e "${RED}错误: JAR文件不存在 - $jar_file${NC}"        return 1    fi        echo -e "${BLUE}部署新版本...${NC}"        # 停止当前服务    ./springboot-service-manager.sh stop "$APP_NAME" 2>/dev/null || true        # 等待服务完全停止    sleep 3        # 复制新版本    cp "$jar_file" "$DEPLOY_DIR/$JAR_NAME"    chmod +x "$DEPLOY_DIR/$JAR_NAME"        echo -e "${GREEN}部署完成${NC}"}# 健康检查health_check() {    local max_attempts=30    local attempt=0        echo -e "${BLUE}进行健康检查...${NC}"        while [[ $attempt -lt $max_attempts ]]; do        if curl -s -f "http://localhost:$SERVICE_PORT/actuator/health" >/dev/null 2>&1; then            echo -e "${GREEN}健康检查通过!${NC}"            return 0        fi                attempt=$((attempt + 1))        echo -n "."        sleep 2    done        echo    echo -e "${RED}健康检查失败!${NC}"    return 1}# 回滚到上一版本rollback() {    echo -e "${YELLOW}开始回滚...${NC}"        # 查找最新的备份文件    local latest_backup=$(ls -t "$BACKUP_DIR"/${JAR_NAME}.*.bak 2>/dev/null | head -1)        if [[ -z "$latest_backup" ]]; then        echo -e "${RED}没有找到备份文件${NC}"        return 1    fi        echo -e "${BLUE}回滚到: $latest_backup${NC}"        # 停止当前服务    ./springboot-service-manager.sh stop "$APP_NAME" 2>/dev/null || true    sleep 3        # 恢复备份    cp "$latest_backup" "$DEPLOY_DIR/$JAR_NAME"        # 启动服务    ./springboot-service-manager.sh start "$APP_NAME"        # 健康检查    if health_check; then        echo -e "${GREEN}回滚成功!${NC}"    else        echo -e "${RED}回滚后健康检查失败${NC}"        return 1    fi}# 完整部署流程full_deploy() {    local jar_file=$1        echo -e "${GREEN}开始部署 $APP_NAME${NC}"    echo "JAR文件: $jar_file"    echo "部署目录: $DEPLOY_DIR"    echo "服务端口: $SERVICE_PORT"    echo "环境配置: $PROFILE"    echo "----------------------------------------"        # 创建目录    setup_directories        # 备份当前版本    backup_current_version        # 部署新版本    if ! deploy_new_version "$jar_file"; then        echo -e "${RED}部署失败${NC}"        return 1    fi        # 启动服务    echo -e "${BLUE}启动服务...${NC}"    ./springboot-service-manager.sh start "$APP_NAME"        # 健康检查    if health_check; then        echo -e "${GREEN}部署成功!${NC}"                # 清理旧备份(保留最近5个)        echo -e "${BLUE}清理旧备份...${NC}"        ls -t "$BACKUP_DIR"/${JAR_NAME}.*.bak 2>/dev/null | tail -n +6 | xargs rm -f        echo -e "${GREEN}清理完成${NC}"    else        echo -e "${RED}部署失败,开始回滚...${NC}"        rollback        return 1    fi}# 显示使用帮助show_help() {    echo "SpringBoot应用部署脚本"    echo    echo "用法:"    echo "  $0 deploy <jar-file>    - 部署新版本"    echo "  $0 rollback             - 回滚到上一版本"    echo "  $0 health               - 健康检查"    echo "  $0 setup                - 初始化部署环境"    echo    echo "示例:"    echo "  $0 deploy app-1.0.0.jar"    echo "  $0 rollback"}# 主程序main() {    case "${1:-}" in        deploy)            if [[ -z "${2:-}" ]]; then                echo -e "${RED}错误: 请指定JAR文件${NC}"                show_help                exit 1            fi            full_deploy "$2"            ;;        rollback)            rollback            ;;        health)            health_check            ;;        setup)            setup_directories            ;;        *)            show_help            ;;    esac}main "$@"

发表评论

泰日号Copyright Your WebSite.Some Rights Reserved. 网站地图 备案号:川ICP备66666666号 Z-BlogPHP强力驱动