前言😊

传统部署 Spring Boot 项目,需要手动执行mvn package打包、上传服务器、解压文件、启停服务,流程繁琐且容易出错😫。阿里云效 Flow 作为阿里云推出的免费 CI/CD 工具🎁,与阿里云 ECS、CodeUp、制品仓库深度集成,无需复杂配置即可实现自动化部署。

本文基于真实实操经验,每一步都附详细说明和可直接复制的代码,新手也能轻松搭建企业级自动化部署流水线🌈。


环境准备📌

在开始之前,你需要提前准备好以下环境:

  1. 阿里云账号:开通云效 Flow(免费版足够个人 / 小型项目使用)、ECS 服务器(CentOS 7+,安装 JDK 8+)。
  2. 代码仓库:Spring Boot 项目代码托管在阿里云 CodeUp、GitHub 或 Gitee,本文以阿里云 CodeUp 为例。
  3. 基础依赖:ECS 服务器已安装 Java 8+(Spring Boot 项目运行依赖)。

第一步:初始化代码仓库与分支规范📂

2.1 创建 CodeUp 仓库👉

  1. 登录阿里云控制台,进入「云效」→「CodeUp」,点击「新建仓库」,填写仓库名称(如demo-springboot),选择「私有仓库」,点击「创建」。
  2. 将本地 Spring Boot 项目代码推送到该仓库,确保根目录包含pom.xmlsrc目录和启动类文件。

2.2 分支规范设置✨

  • 主分支:master,用于流水线部署触发。
  • 开发分支:基于master创建个人分支(如dev-nick),开发完成后合并到master,触发流水线自动部署。

第二步:创建流水线并配置代码源⚙️

3.1 新建流水线👆

  1. 在 CodeUp 仓库首页,点击顶部「流水线」图标,进入流水线管理页面。
  2. 点击「新建流水线」,选择可视化编排(新手友好),模板选择「Java・测试、构建、部署到阿里云 ECS / 自有主机」,点击「创建」。
  3. 修改流水线名称为demo-springboot-自动化部署流水线,点击「仅保存」。

3.2 配置代码源触发💡

  • 流水线流程配置页,点击「代码源」任务,选择你创建的 CodeUp 仓库,触发分支选择master,触发方式为「代码提交触发」。

第三步:配置 Java 构建与制品上传📦

4.1 配置 Maven 构建👇

  1. 点击「Java 构建上传」任务,进入配置界面。
  2. JDK 版本选择与项目一致(如 Java 8),Maven 版本默认即可。
  3. 构建命令使用默认的mvn clean package -DskipTests(跳过单元测试,加快构建速度)。

4.2 配置制品仓库(关键步骤✅)

  1. 上传方式选择「组织私有通用制品仓库」。
  2. 点击「添加服务连接」→「新建制品仓库」,仓库类型选择「通用制品」,名称自定义(如demo-package),仓库模式为「Hybrid 综合模式」,公开性选「私有仓库」,点击「创建」。
  3. 制品仓库选择刚创建的demo-package,制品名称默认Artifacts_${PIPELINE_ID},制品版本默认${BUILD_NUMBER},打包路径填写target/(Spring Boot 打包后 Jar 包默认存放目录)。
  4. 点击「保存」,流水线会自动将target/目录下的 Jar 包打包为package.tgz并上传到制品仓库。为了统一制品格式,方便与部署脚本解耦,且压缩传输更高效。

第四步:配置主机部署(绑定 ECS + 部署脚本)🖥️

5.1 新建主机组并绑定 ECS🐰

  1. 点击「主机部署」任务,进入配置界面。
  2. 点击「主机组」→「新建主机组」,主机组名称自定义(如demo-ecs-host-group),点击「确定」。
  3. 点击「添加新主机」,选择「阿里云 ECS」,选择你的 ECS 实例,点击「保存」,完成 ECS 与主机组的绑定。
  4. 制品选择:下拉框选择「制品名称.default」(即上一步构建上传的package.tgz)。

5.2 部署脚本编写(避坑核心⚠️)

这里是新手最容易踩坑的地方:流水线默认脚本路径为/home/admin/app/,但制品包默认下载至/root/,路径不匹配会导致解压失败、脚本找不到等问题。

正确的部署脚本(适配 /root 路径,直接复制使用):

# 解压制品包(下载路径/root/,解压至/root/)
tar zxvf /root/package.tgz -C /root/
# 执行重启脚本(适配/root路径下的deploy.sh)
sh /root/deploy.sh restart

第五步:ECS 服务器配置(编写启停脚本 + 授权)🐻

6.1 登录 ECS 服务器☁️

通过阿里云控制台「ECS」→「远程连接」,或 Xshell 工具登录 ECS,默认用户为root

6.2 编写 deploy.sh 启停脚本📝

6.2.1 创建脚本文件👇

进入/root目录,执行以下命令创建脚本:

cd /root
vi deploy.sh
6.2.2 粘贴完整脚本内容(适配 demo 项目)✨
#!/bin/bash
# 项目目录(与解压路径一致)
APP_HOME="/root"
# Jar包名称(流水线打包生成,可通过ls /root/*.jar查看)
JAR_NAME="demo-0.0.1-SNAPSHOT.jar"
# 日志文件路径
LOG_FILE="$APP_HOME/app.log"
# JVM参数(适配ECS配置,256M-512M内存)
JVM_OPTS="-Xms256m -Xmx512m"

# 停止旧进程
stop() {
    echo "正在停止旧进程..."
    PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
    if [ -n "$PID" ]; then
        kill $PID
        sleep 2
        # 强制杀死未退出进程
        PID_CHECK=$(ps -p $PID --no-headers)
        if [ -n "$PID_CHECK" ]; then
            echo "进程未响应,强制终止..."
            kill -9 $PID
        fi
        echo "进程已停止"
    else
        echo "未找到运行中的进程,无需停止"
    fi
}

# 启动新进程
start() {
    echo "正在启动项目..."
    cd $APP_HOME || exit 1
    # 后台启动,日志输出至文件
    nohup java $JVM_OPTS -jar $JAR_NAME > $LOG_FILE 2>&1 &
    echo "启动完成,日志路径:$LOG_FILE"
}

# 主逻辑:仅支持restart命令
case "$1" in
    restart)
        stop
        start
        ;;
    *)
        echo "用法:$0 restart"
        exit 1
        ;;
esac

在 deploy.sh 的 stop 函数中,kill $PID 后有个 sleep 2 和二次检查强杀的逻辑。这里非常棒,它是一个高级的“优雅停机”实践。建议突出强调这个小设计:先给进程2秒时间处理完现有请求,再强制终止,可以避免数据丢失或请求中断。

6.2.3 保存并授权脚本✅
  1. 保存退出:按Esc,输入:wq,回车保存。
  2. 赋予执行权限(关键步骤,否则脚本无法运行):
chmod +x /root/deploy.sh

6.3 验证脚本可用性🎯

手动执行脚本,测试启停功能:

/root/deploy.sh restart
  • 输出「启动完成,日志路径:/root/app.log」,说明脚本正常。
  • 查看日志确认项目启动成功:
tail -f /root/app.log

出现「Started DemoApplication in X seconds」即表示项目启动成功。

6.4 ECS 安全组配置(外网访问🌐)

若外网无法访问项目(默认 8080 端口),进入阿里云 ECS 控制台→「安全组」→「配置规则」,放行8080 端口(入方向,允许所有 IP 访问)。


第六步:运行流水线并验证部署🚀

7.1 触发流水线👆

  1. 回到云效流水线配置页,点击「保存并运行」,手动触发流水线。
  2. 等待流水线执行(约 2-5 分钟),依次完成「代码扫描→构建上传→主机部署」,全部显示绿色「成功」即部署完成。

7.2 验证部署结果💯

  1. 服务器验证:登录 ECS,执行ps -ef | grep java,可看到demo-0.0.1-SNAPSHOT.jar进程。
  2. 外网验证:浏览器访问「ECS 公网 IP:8080」,可正常访问 Spring Boot 项目页面。

7.3 自动部署验证✨

修改本地代码,提交并合并至master分支,流水线会自动触发,完成构建与部署,无需手动操作。


高频问题避坑指南(必看⚠️)

问题 1:解压报错「tar: Old option 'g' requires an argument」

  • 原因:流水线脚本路径与制品包下载路径不一致,或脚本格式错误。
  • 解决:统一路径为/root/,复制本文提供的标准部署脚本,避免手动修改格式。

问题 2:启动报错「sh: /root/deploy.sh: No such file or directory」

  • 原因deploy.sh不存在,或未赋予执行权限。
  • 解决:重新创建脚本,执行chmod +x /root/deploy.sh授权。

问题 3:项目启动成功,但外网无法访问

  • 原因:ECS 安全组未放行 8080 端口,或项目端口被占用。
  • 解决:放行安全组 8080 端口;停止占用端口的进程,重启项目。

问题 4:Jar 包名称错误,导致进程无法启动

  • 原因deploy.shJAR_NAME与实际 Jar 包名不一致。
  • 解决:执行ls /root/*.jar查看真实 Jar 包名,同步修改deploy.sh中的JAR_NAME

总结与优化建议🌈

本文完整实现了云效 Flow 流水线 + ECS的 Spring Boot 项目自动化部署,核心要点总结:

  1. 路径统一:制品包下载路径、解压路径、启停脚本路径必须一致,优先使用/root/(root 用户权限充足)。
  2. 脚本规范:部署脚本仅保留核心解压与启停命令;deploy.sh必须授权执行权限,适配真实 Jar 包名。
  3. 生态联动:云效 Flow 与阿里云 ECS、CodeUp、制品仓库深度集成,无需额外配置,新手按步骤即可跑通。

进阶优化建议:

进阶技巧:你可以给重要的发布版本在制品仓库中打上标签,例如 release-v1.2.3,这样回滚时更容易识别。

  • 在云效Flow中,每次构建都会在制品仓库中生成一个带唯一版本号的制品包。利用这一点,我们可以实现一键回滚到任意历史版本

    操作步骤:

  • 查看历史制品:进入“云效Flow -> 制品仓库”,找到你的应用,可以看到所有历史构建的制品列表,每个都有对应的时间戳和版本号。

  • 手动回滚部署

    • 进入你的流水线,点击“编辑”。

    • 找到“主机部署”任务,在“部署配置”中,将“制品版本”从“最新”切换为“指定版本”。

    • 从列表中选择你想要回滚的那个稳定版本,保存流水线。

  • 执行回滚:点击“运行流水线”,它就会拉取你指定的旧版制品包进行部署,完成回滚。


📢附录:

1. 带健康检查的部署脚本(deploy.sh 升级版)

这个脚本在你原版基础上,增加了启动后的健康检查逻辑,确保应用不仅进程启动,而且能正常响应请求后再宣告部署成功。需要先在Spring Boot项目中引入actuator依赖。

#!/bin/bash
# 项目目录(与流水线解压路径一致)
APP_HOME="/root"
# Jar包名称(请根据实际情况修改)
JAR_NAME="demo-0.0.1-SNAPSHOT.jar"
# 日志文件路径
LOG_FILE="$APP_HOME/app.log"
# JVM内存参数
JVM_OPTS="-Xms256m -Xmx512m"
# 健康检查URL(依赖Spring Boot Actuator)
HEALTH_CHECK_URL="http://127.0.0.1:8080/actuator/health"
# 健康检查超时时间(秒)
HEALTH_CHECK_TIMEOUT=60

# 停止旧进程
stop() {
    echo "正在停止旧进程..."
    PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
    if [ -n "$PID" ]; then
        kill $PID
        sleep 2
        if ps -p $PID > /dev/null 2>&1; then
            echo "进程未响应,强制终止..."
            kill -9 $PID
        fi
        echo "进程已停止"
    else
        echo "未找到运行中的进程,无需停止"
    fi
}

# 启动新进程并等待健康检查通过
start() {
    echo "正在启动项目..."
    cd $APP_HOME || exit 1
    nohup java $JVM_OPTS -jar $JAR_NAME > $LOG_FILE 2>&1 &
    
    echo "正在等待应用启动并执行健康检查..."
    local elapsed=0
    while [ $elapsed -lt $HEALTH_CHECK_TIMEOUT ]; do
        sleep 2
        elapsed=$((elapsed + 2))
        
        # 检查健康状态
        HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_CHECK_URL 2>/dev/null)
        if [ "$HTTP_CODE" = "200" ]; then
            echo "✅ 应用启动成功!健康检查通过 (耗时 ${elapsed}s)"
            echo "日志路径:$LOG_FILE"
            return 0
        fi
        echo "等待健康检查... (已等待${elapsed}s)"
    done

    echo "❌ 错误:启动超时,健康检查未通过。请检查日志:$LOG_FILE"
    return 1
}

# 重启逻辑
case "$1" in
    restart)
        stop
        start
        ;;
    *)
        echo "用法:$0 restart"
        exit 1
        ;;
esac
2. 应用保活定时任务(CRON配置)

将下面这行配置加入crontab,可以每5分钟自动检查一次应用健康状态。如果应用挂了,会自动执行重启脚本,实现简单的故障自愈,非常适合在监控体系完善前作为兜底方案。

# 编辑定时任务
crontab -e

# 添加此行:每5分钟检查一次,失败则重启
*/5 * * * * /usr/bin/curl -f http://127.0.0.1:8080/actuator/health || /root/deploy.sh restart

提醒:使用此定时任务前,请确保已部署上面的“带健康检查的部署脚本”,并且curl命令已安装在服务器上。

感谢观看😊

以上就是阿里云效 Flow 流水线部署 Spring Boot 项目的全流程啦✨,从 0 到 1 手把手配置,附完整避坑指南💡,希望能帮到正在学习自动化部署的小伙伴🐱!

如果本文对你有帮助,欢迎点赞👍、收藏⭐、关注❤️,后续会持续更新更多实战教程与避坑技巧💯!

有任何问题,欢迎评论区留言交流🙏!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐