跳过正文
Background Image
  1. Posts/

如何优雅地控制 Jenkins 构建是否中断?只看这篇

·1033 字·3 分钟· ·
沈显鹏
作者
沈显鹏
目录

背景介绍
#

在我们的 Jenkins 流水线中,经常会遇到这样一种情况:当同一个分支或 PR 已有一个构建任务正在运行时,如果此时有新的提交进来,当前构建会被自动中断,转而执行新的构建任务。

这是由于我们需要合理控制资源使用,尤其是对于那些构建时间较长的任务。如果允许同一个分支或 PR 同时触发多个构建,Jenkins Agents 很快就会被大量占用,导致后续任务只能排队等待。

因此,在 Jenkinsfile 中,我们经常会设置这样的选项:

// 禁止并发构建,允许中断前一个任务
disableConcurrentBuilds abortPrevious: true

这段代码你可能在不少 Jenkinsfile 中看到,就算是 Jenkins 团队他们自己的 CI 也是这样设置的。

Jenkins buildPlugin.groovy

这样做的好处是显而易见的,但在某些情况时也带来了一个新的问题,比如:

当一个 release 分支正在运行的构建任务,会被新的合并触发的构建中断。尤其是当它即将完成时,却因为新的合并代码触发了新的构建任务,导致前一个任务被中断。

这让 QA 同事很抓狂:一个马上就要交付测试的 Build,结果因为新的合并被中断了,还得重新等待……

于是他们提出了一个需求:

PR 构建可以中断来节省资源没问题,但像 develrelease 分支上的构建,如果已经在运行,就不应该被中断。新的合并触发的构建应该排队等待,直到前一个任务完成后再运行。

起初我认为这个设置是全局生效的,没办法按分支进行区分。查了一下 ChatGPT 和 Google,也确实没发现特别简单的方法能做到“某些分支不中断,而是排队”。

后来我想到了一个非常简单的做法:

可以通过一段简单的判断逻辑,在 pipeline 的起始位置判断当前构建是基于哪个分支,然后根据分支类型动态设置 abortPrevious 的值:

def call() {
    def isAboutPrevious = true

    if (env.BRANCH_NAME == 'devel' || env.BRANCH_NAME.startsWith('release/')) {
        isAboutPrevious = false // devel 和 release 分支,不中断
    }

    pipeline {
        options {
            disableConcurrentBuilds abortPrevious: isAboutPrevious
        }
        stages {
            // ... 构建流程
        }
    }
}

最终效果
#

这段逻辑已经合并到了我们的共享 Jenkins 库中。上线后的表现完全符合预期:

✅ 同一个 devel / release 分支上的构建任务会排队执行,不再中断 ✅ 同一个 PR 的构建依然会中断前一个任务,从而节省资源 ✅ 无需单独创建 Jenkinsfile,也没有引入复杂逻辑,维护成本极低

改动之前是这样的:

What’s the difference?

  • Job #104:还没跑完就被中断了
  • Job #105:同样的命运,又被新合并触发的构建终止了

我们希望达到的效果是:

  • Job #106:即使有新的合并,也能继续正常运行
  • Job #107:在队列中等待,等 #106 完成后再开始执行

总结一下
#

如果你也在使用 Jenkins 进行多分支构建,并且对某些特定分支有类似的需求,这个方法值得一试:

简单的一段条件判断,就可以实现按需控制构建是否会被中断。

欢迎大家在留言区交流你们的 Jenkins 构建优化经验!👋


转载本站文章请注明作者和出处,请勿用于任何商业用途。欢迎关注公众号「DevOps攻城狮」

相关文章

从 Jenkins 升级,我做了哪些优化
·949 字·2 分钟
本文介绍了在升级 Jenkins 的过程中所做的优化,包括使用 Docker Compose 部署、重构 Jenkins Shared Library、引入 Windows Docker Container 等,以提升 CI/CD 流程的效率和安全性。
备份 Jenkins 的方法
·442 字·1 分钟
介绍如何使用 ThinBackup 插件或 Shell 脚本备份 Jenkins,确保 Jenkins 配置和构建数据安全存储。
每个 Jenkins 用户都应该知道这三个最佳实践
·1603 字·4 分钟
本文介绍了 Jenkins 的三个最佳实践:配置即代码、Jenkins 共享库和多分支流水线,帮助用户提升 Jenkins 的使用效率和质量。
北京48小时:记一次参加 DevOps 训练营
·1884 字·4 分钟
记录我在北京参加 JFrog DevOps 训练营的经历,分享培训内容和个人感受,以及对未来工作的思考。
如何通过 Jenkins 进行资源的锁定和释放
·901 字·2 分钟
本文介绍了如何使用 Jenkins 的 Lockable Resources 插件来管理和锁定资源,确保在多任务环境中资源的独占性和安全性。
通过 Jenkins 来提交修改的代码 git push by Jenkins
·439 字·1 分钟
如何通过 Jenkins Pipeline 脚本来提交修改的代码到 Git 仓库,包括克隆仓库、修改代码和推送更改等步骤。