Skip to content
CI/CD 与发布治理 · 第 3 篇 / 共 8 篇
领域运维与部署
专题CI/CD 与发布治理专题
当前序列CI/CD 与发布治理
阅读位置第 3 篇 / 共 8 篇当前专题第 1 个序列 / 共 4 个序列

Jenkins 发布 Java 服务实战:从 Maven 打包、镜像构建到远程部署

对很多 Java 团队来说,Jenkins 仍然是最常见的 CI/CD 工具之一。

原因很现实:

  • 老项目多
  • 自建环境多
  • 可控性强

先说结论

如果你要用 Jenkins 发布一个 Java 服务,一条更稳妥的链路通常是:

text
拉代码 -> Maven 测试/打包 -> 构建 Docker 镜像 -> 推送镜像仓库 -> 远程拉起新版本 -> 健康检查

真正要注意的,不是 Jenkinsfile 语法本身,而是:

  • 构建机环境是否一致
  • 制品是否可追踪
  • 发布动作是否可回滚

一、Jenkins 在 Java 项目里通常承担什么角色

它主要负责两件事:

  • 自动执行构建链路
  • 固化发布流程

也就是说,Jenkins 最有价值的地方不是“页面点一下就上线”,而是让构建和发布不再依赖某个人的手工操作顺序。

二、一个典型 Java 服务流水线分几段

1. 代码拉取

从 Git 仓库获取指定分支代码。

2. 编译与测试

例如:

bash
mvn clean test
mvn clean package -DskipTests

3. 镜像构建

更推荐把服务打成镜像,而不是每次手动复制 jar。

因为镜像更容易:

  • 固化运行环境
  • 做版本管理
  • 支持回滚

4. 推送镜像仓库

例如推到:

  • Harbor
  • Docker Hub
  • 阿里云容器镜像服务

5. 远程部署

常见做法包括:

  • SSH 到服务器执行 docker compose pull && docker compose up -d
  • 或执行自定义部署脚本

6. 健康检查

例如:

  • curl /actuator/health
  • 检查容器状态
  • 看最近日志是否有启动失败关键字

三、为什么 Java 服务更适合镜像化发布

很多团队还在用:

  • 本地打 jar
  • 传到服务器
  • 手工 nohup java -jar

这种方式不是不能用,但长期维护问题很多:

  • JDK 版本容易飘
  • 启动参数容易散落
  • 回滚不方便

如果改成镜像化,很多东西就能固定下来:

  • 基础运行环境
  • JVM 参数
  • 暴露端口
  • 启动命令

四、一个简化版 Jenkinsfile 示例

groovy
pipeline {
  agent any

  environment {
    IMAGE_NAME = "registry.example.com/demo/order-service"
    IMAGE_TAG = "${BUILD_NUMBER}"
  }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }

    stage('Build') {
      steps {
        sh 'mvn clean package -DskipTests'
      }
    }

    stage('Docker Build') {
      steps {
        sh 'docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .'
      }
    }

    stage('Push Image') {
      steps {
        sh 'docker push ${IMAGE_NAME}:${IMAGE_TAG}'
      }
    }

    stage('Deploy') {
      steps {
        sh '''
          ssh ubuntu@server '
            docker pull ${IMAGE_NAME}:${IMAGE_TAG} &&
            export IMAGE_TAG=${IMAGE_TAG} &&
            cd /mydata/apps/order-service &&
            docker compose up -d
          '
        '''
      }
    }
  }
}

五、Jenkins 项目里最常见的几个坑

1. Jenkins 机器环境太脏

比如:

  • Maven 配置混乱
  • JDK 版本不统一
  • Docker 权限不稳定

2. 每次上线都重新写远程命令

如果发布逻辑散落在 Jenkins 页面配置里,后期维护会很痛苦。

更稳妥的做法是:

  • 把部署脚本放进仓库
  • Jenkins 只负责调用

3. 只关心构建成功,不关心服务是否真的可用

真正线上问题经常出在:

  • 启动成功但依赖没连上
  • 配置错误导致接口不可用
  • 数据库脚本没跟上

所以健康检查一定要补。

4. 没有版本回滚策略

如果镜像标签只用 latest,发布出问题时回滚会很狼狈。

更推荐:

  • 镜像标签带构建号或 Git Commit
  • 上一版本镜像可快速重启

六、适合 Java 团队的更稳落地方式

如果你们现在还是半手工发布,可以按这个顺序逐步推进:

第一步:先让 Jenkins 稳定打包

第二步:把 jar 改成镜像构建

第三步:把远程部署脚本化

第四步:补健康检查和回滚

七、什么时候 Jenkins 不一定是最优选

如果你是:

  • 个人项目
  • 小团队
  • 项目主要托管在 GitHub

那 Jenkins 不一定比 GitHub Actions 更省心。

但如果你是:

  • 公司内网项目
  • 多 Java 服务
  • 已有自建发布体系

Jenkins 仍然很实用。

一句话总结

Jenkins 对 Java 服务最核心的价值,不是提供一个页面,而是把“构建、制品、部署、验证”这一整套流程沉淀成可以重复执行的工程能力。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读GitLab CI/CD 实战:Docker 构建镜像并通过 SSH 部署到服务器适合沿着流水线设计、自动部署、发布策略、数据库变更和多环境治理这条线往下读。CI/CD 与发布治理专题 · CI/CD 与发布治理同一序列 · 顺着当前主线继续读灰度、蓝绿、滚动发布到底怎么选:以及上线失败后怎么回滚适合沿着流水线设计、自动部署、发布策略、数据库变更和多环境治理这条线往下读。CI/CD 与发布治理专题 · CI/CD 与发布治理同专题其他序列 · 共享标签:CI/CD、部署交付灰度发布和 feature flag 应该怎么配合适合把缓存、制品库、灰度发布、数据库变更和回滚演练放在同一条 CI/CD 主线上看。CI/CD 与发布治理专题 · CI/CD 流水线稳定性与发布治理同专题其他序列 · 共享标签:CI/CD、部署交付回滚演练到底要演什么适合把缓存、制品库、灰度发布、数据库变更和回滚演练放在同一条 CI/CD 主线上看。CI/CD 与发布治理专题 · CI/CD 流水线稳定性与发布治理跨专题关联 · 共享标签:CI/CD、部署交付镜像分层为什么会影响构建速度和回滚适合把镜像分层、镜像瘦身、时区日志、静态缓存和 WebSocket 代理放进一条容器交付主线上看。容器与站点部署专题 · 容器镜像与站点交付细节跨专题关联 · 共享标签:CI/CD、部署交付Deployment 回滚到底依赖了什么信息适合把命名空间、回滚、PDB、HPA、Mesh 和调度约束放在一条 Kubernetes 治理主线上整理。Kubernetes 专题 · Kubernetes 编排约束与交付治理
继续阅读CI/CD 与发布治理当前序列第 3 篇 / 共 8 篇当前专题第 1 个序列 / 共 4 个序列
往前看
上一篇流水线阶段、门禁和发布卡点怎么设计回到当前序列上一章上一序列Docker 与 Nginx 部署从第 1 篇开始:Docker 常用命令速查
往后看
下一篇GitLab CI/CD 实战:Docker 构建镜像并通过 SSH 部署到服务器继续当前序列下一章下一序列CI/CD 流水线核心模型从第 1 篇开始:流水线阶段和门禁到底该怎么拆

把零散经验整理成可查、可复用、可持续更新的企业级知识门户