企业级后端部署方案:Jenkins + MinIO + SSH + Gitee + Jenkinsfile 自动化实践
本文档基于
jenkinsfileTest/backend.jenkinsfile及共享库jenkinslib编写,描述 Java 后端从 Maven/Gradle 编译、JAR 制品入库(含保留策略)、多机 SSH 部署(启动脚本模板/自定义、指定启动用户)到回滚的完整流程。
一、方案架构
1.1 组件说明
| 组件 | 角色 | 说明 |
|---|---|---|
| Gitee | 代码仓库 | SSH 拉取指定分支 |
| Jenkins (master) | CI/CD | 编译、上传 MinIO、SSH 部署、launch.sh 重启 |
| MinIO | 制品仓库 | 版本化 JAR,自动清理超额历史包 |
| 应用服务器 | 运行节点 | SSH 拉 JAR + bin/launch.sh restart |
| Apollo | 配置中心 | 脚本模板模式注入 JVM 参数 |
1.2 目标机目录结构
{destPath}/ ├── order-service-20250618_143022-a1b2c3d.jar # 当前 JAR(保留 N 个历史 JAR) └── bin/ └── launch.sh # start / stop / restart1.3 流水线与共享库
| 文件 | 说明 |
|---|---|
backend.jenkinsfile | 后端流水线入口 |
pipeline.groovy | checkout、发布门禁、回滚选版 |
build.groovy | compile()mvn/gradle |
deploy.groovy | MinIO 上传/清理、SSH 部署、launch 脚本生成 |
resources/backend-launch-template.sh | 默认 bash 启动脚本 |
tools.groovy | publishMode、startScriptType 归一化 |
config.groovy | 凭据、MinIO、默认保留数 |
二、发布模式(publishMode)
| publishMode | 行为 |
|---|---|
| 自动发布(默认) | 构建上传后自动部署 |
| 手动发布 | input 确认后部署 |
| 仅构建 | 仅上传 MinIO,不 SSH 部署 |
| 回滚 | 选历史 JAR 部署 |
三、时序图(自动发布)
四、启动脚本
4.1 脚本模板模式(startScriptType=脚本模板)
共享库backend-launch-template.sh,支持start/stop/restart。
停服逻辑(已修复):按应用目录${app_dir}匹配 Java 进程,而非按带时间戳的 JAR 文件名,避免换 JAR 后旧进程停不掉。
find_pid(){ps-ef|grepjava|grep"${app_dir}/"|grep-vgrep|awk'{print $2}'|head-1}占位符:{{PRONAME}}{{JARNAME}}{{JVM_OPTS}}{{APOLLO_*}}
4.2 自定义脚本模式
- 上传
launchScriptFile或填写customScriptContent(至少一种) - 同样支持占位符替换
4.3 启动用户(runUser)
chown-R${runUser}${destPath}sudo-u${runUser}bashbin/launch.sh restart五、Jenkins 配置
5.1 参数化构建
基础参数
| 参数名 | 类型 | 说明 |
|---|---|---|
Tenv | Choice | dev/test/prod |
publishMode | Choice | 必配:自动发布/手动发布/仅构建/回滚 |
projectName | String | 应用名,JAR 命名与 MinIO 路径 |
buildType | Choice | mvn / gradle |
buildshell | String | 如 clean package -DskipTests |
buildPath | String | JAR 搜索目录,默认 target |
destPath | String | 目标机应用根目录 |
destIp | String | 部署服务器,逗号分隔 |
artifactRetainCount | String | MinIO + 目标机保留 JAR 数,默认 10 |
waitMins/emailUser | String | 手动超时 / 邮件 |
发布配置
| 参数名 | 说明 |
|---|---|
runUser | 启动用户,默认 app |
startScriptType | 脚本模板 / 自定义脚本 |
customScriptContent | 自定义脚本文本 |
launchScriptFile | File Parameter 上传脚本 |
JVM / Apollo(模板模式)
| 参数名 | 默认值 |
|---|---|
JVM_OPTS | -server -Xmx1024m … |
APOLLO_ENV | PRO |
APOLLO_META | http://apollo-eurka-service/ |
APOLLO_NAMESPACES | bigdata.configuration,application,… |
5.2 制品保留策略
| 位置 | 机制 |
|---|---|
| MinIO | uploadToMinio后pruneMinioArtifacts,保留最新 N 个 JAR |
| 应用服务器 | 部署时删除{destPath}/{projectName}-*.jar超额旧文件 |
N 由artifactRetainCount控制(默认 10,见config.DEFAULT_ARTIFACT_RETAIN_COUNT)。
5.3 凭据与环境变量
同前端文档:gitee_registry_ssh、minio-credentials、SSH 凭据;可选MINIO_ENDPOINT、MINIO_BUCKET(默认 backend-artifacts)、SSH_KEY_CREDENTIAL_ID。
六、流水线阶段
| 阶段 | 条件 | 说明 |
|---|---|---|
| CheckOut | ≠ 回滚 | pipeline.checkoutCode |
| 代码编译 | 同上 | build.compile,find JAR,命名{projectName}-{BUILD_TIME}-{GIT_COMMIT}.jar |
| 打包并上传 MinIO | 同上 | cp + uploadToMinio + prune |
| 发布 | auto/manual | runPublish → deployBackendJar |
| 回滚 | rollback | selectRollbackVersion → deployBackendJar |
| post | always | sendPost 合并邮件 |
七、共享库 API
deploy.groovy
| 方法 | 说明 |
|---|---|
uploadToMinio(..., retainCount) | 上传 JAR 并清理 MinIO |
deployBackendJar(...) | SSH 部署 + launch.sh + 本地 JAR 清理 |
resolveCustomScriptFile(script) | 解析上传的脚本文件 |
buildLaunchScript(内部) | 模板/自定义 + 占位符 |
tools.groovy
normalizePublishMode()— 发布模式normalizeStartScriptType()— 脚本模板/自定义parseRetainCount()— 解析保留个数
八、典型场景
| 场景 | publishMode | 备注 |
|---|---|---|
| 日常 Apollo 发版 | 自动发布 | startScriptType=脚本模板 |
| 构建不上线 | 仅构建 | 制品仍上传 MinIO |
| 自定义启动脚本 | 自动发布 | 上传 launchScriptFile |
| 回滚 | 回滚 | 使用当前 runUser/脚本配置生成 launch.sh |
| 磁盘控制 | 任意 | artifactRetainCount=5 |
九、排错
| 现象 | 处理 |
|---|---|
| 未找到 JAR | 检查 buildPath、buildshell |
| 双实例/端口占用 | 确认 launch.sh 已更新(find_pid 按 app_dir) |
| 自定义脚本报错 | 提供 launchScriptFile 或 customScriptContent |
| 回滚版本少 | retain 过小导致 MinIO 旧包被删,调大保留数 |
| sudo 失败 | 配置 sudoers 或 SSH 用户=runUser |
十、快速检查清单
- 共享库含 backend-launch-template.sh
- 目标机已创建 runUser,sudo 权限正确
- publishMode、artifactRetainCount 已配置
- projectName 与 MinIO 路径一致
- Apollo 地址在目标机可达(模板模式)