在 Linux 服务器实现 Spring Boot 项目的自动化部署与版本回滚
在持续集成和持续部署(CI/CD)的实践中,自动化部署和版本回滚是确保服务高可用的关键步骤。本文将详细介绍如何在 Linux 服务器上实现以下目标。
·
在持续集成和持续部署(CI/CD)的实践中,自动化部署和版本回滚是确保服务高可用的关键步骤。本文将详细介绍如何在 Linux 服务器上实现以下目标
- 从 Git 仓库拉取最新代码
- 停止当前运行的 Spring Boot 服务
- 重新打包项目并部署到指定目录
- 支持一键版本回滚
一、准备工作
1.服务器环境要求
- Java 环境:安装 JDK 8+(确保 java -version 可运行)。
- Maven:用于项目打包(确保 mvn -v 可运行)。
- Git:用于代码拉取(确保 git --version 可运行)。
- 目录权限:确保对 /opt/server 目录有读写权限。
2. 项目结构
假设 Spring Boot 项目名为 dafu-admin,打包后的文件为 dafu-admin.jar,部署目录为 /opt/server。
二、自动化部署脚本
- 脚本功能
- 从 Git 拉取最新代码
- 停止正在运行的旧服务
- 使用 Maven 重新打包项目
- 备份旧版本
- 部署新版本到 /opt/server
- 启动新服务
- 支持回滚到任意历史版本
三、使用说明
1. 首次部署
chmod +x deploy.sh # 赋予执行权限
./deploy.sh # 执行部署
2. 后续更新
直接运行脚本即可完成全流程:
./deploy.sh
3. 版本回滚
./deploy.sh rollback # 回滚到最近一个备份版本
脚本内容 (deploy.sh)
#!/bin/bash
set -euo pipefail
# 配置区(按需修改)
PROJECT_DIR="/opt/server/" # 项目目录
DEPLOY_DIR="/opt/server/project" # 部署目录
DEPLOY_JAR_DIR="dafu-admin/target" # 项目jar所在目录
BACKUP_DIR="/opt/server/backups" # 备份目录
JAR_NAME="dafu-admin.jar" # 固定JAR名称
MAX_BACKUPS=5 # 最大保留备份数
BUILD_CMD="mvn clean package -DskipTests" # 构建命令
# 日志配置
LOG_FILE="$DEPLOY_DIR/app.log"
# 创建必要目录
sudo mkdir -p "$BACKUP_DIR"
sudo chmod 755 "$BACKUP_DIR"
function backup_current_version() {
if [ -f "$DEPLOY_DIR/$JAR_NAME" ]; then
local timestamp=$(date +%Y%m%d%H%M%S)
local backup_name="${JAR_NAME%.*}_$timestamp.${JAR_NAME##*.}"
echo "正在备份当前版本..."
sudo cp -v "$DEPLOY_DIR/$JAR_NAME" "$BACKUP_DIR/$backup_name"
# 清理旧备份
local backups=($(ls -t "$BACKUP_DIR"/*.jar 2>/dev/null))
if [ ${#backups[@]} -gt $MAX_BACKUPS ]; then
echo "清理旧备份..."
for old_backup in "${backups[@]:$MAX_BACKUPS}"; do
sudo rm -v "$old_backup"
done
fi
fi
}
function rollback_version() {
local backups=($(ls -t "$BACKUP_DIR"/*.jar 2>/dev/null))
if [ ${#backups[@]} -eq 0 ]; then
echo "错误:没有可用的备份版本!"
exit 1
fi
local latest_backup="${backups[0]}"
echo "正在回滚到版本:$(basename $latest_backup)"
# 停止当前服务
PID=$(pgrep -f "$JAR_NAME" || true)
if [ -n "$PID" ]; then
echo "停止当前进程 PID: $PID"
kill "$PID"
while ps -p "$PID" > /dev/null; do
sleep 1
done
fi
# 执行回滚
sudo cp -vf "$latest_backup" "$DEPLOY_DIR/$JAR_NAME"
# 启动服务
echo "启动回滚版本..."
cd "$DEPLOY_DIR"
nohup java -jar "$JAR_NAME" > "$LOG_FILE" 2>&1 &
sleep 3
if ps -p $! > /dev/null; then
echo "回滚成功!新PID: $!"
else
echo "回滚启动失败!检查日志:$LOG_FILE"
exit 1
fi
}
function deploy_new_version() {
# 进入项目目录
cd "$PROJECT_DIR" || {
echo "错误:无法进入项目目录 $PROJECT_DIR"
exit 1
}
# 1. 拉取最新代码
echo "正在从Git仓库拉取更新..."
git pull || {
echo "错误:Git拉取失败!"
exit 1
}
# 2. 停止正在运行的进程
echo "正在停止当前服务..."
PID=$(pgrep -f "$JAR_NAME" || true)
if [ -n "$PID" ]; then
echo "发现运行中的进程 PID: $PID"
kill "$PID"
while ps -p "$PID" > /dev/null; do
sleep 1
done
echo "进程已停止"
else
echo "未找到运行中的服务"
fi
# 3. 构建项目
echo "正在打包项目..."
eval "$BUILD_CMD" || {
echo "错误:项目构建失败!"
exit 1
}
cd "DEPLOY_JAR_DIR"
# 4. 定位生成的JAR文件
JAR_PATH="JAR_NAME"
if [ -z "$JAR_PATH" ]; then
echo "错误:未找到生成的JAR文件!"
exit 1
fi
# 5. 备份当前版本
backup_current_version
# 6. 部署新版本
echo "正在部署新版本到 $DEPLOY_DIR..."
sudo cp -vf "$JAR_NAME" "$DEPLOY_DIR/$JAR_NAME"
# 7. 启动服务
echo "正在启动服务..."
cd "$DEPLOY_DIR"
nohup java -jar "$JAR_NAME" > "$LOG_FILE" 2>&1 &
NEW_PID=$!
sleep 3
if ps -p "$NEW_PID" > /dev/null; then
echo "服务启动成功!PID: $NEW_PID"
else
echo "错误:服务启动失败!"
tail -n 20 "$LOG_FILE"
exit 1
fi
}
# 主流程
case "${1:-}" in
rollback)
rollback_version
;;
*)
deploy_new_version
;;
esac
echo "操作完成!"
更多推荐




所有评论(0)