如何防止Jenkins多分支流水线节点并发作业,允许并行步骤执行
首先非常理解你的痛点——自由风格里用Throttling插件一键配置节点级并发限制太方便了,换到流水线确实容易找不到对应的全局配置方式。不过别担心,有几个优雅的解决方案能满足你的需求,下面逐个说明:
1. 沿用Throttle Concurrent Builds插件(最贴合你的原有习惯)
其实这个插件是支持流水线全局配置的,你不需要给每个步骤单独加节流,只要把整个流水线包裹在节流块里,或者在流水线的options里配置全局属性就行。
方式A:在流水线选项中配置全局节流
这种方式和自由风格的配置逻辑最像,直接指定节点上的最大并发构建数:
pipeline { agent { node { label 'your-specific-slave-node' } } options { // 配置节点级并发限制,同一节点上该作业最多1个实例运行 throttleJobProperty( maxConcurrentPerNode: 1, // 如果需要限制整个作业的总并发数,也可以加上maxConcurrentTotal: 1 categories: ['your-job-group'] // 可选,把多个作业归为一类统一限制 ) } stages { stage('Build') { steps { echo 'Building...' } } stage('Parallel Tests') { parallel { stage('Unit Tests') { steps { echo 'Running unit tests...' } } stage('Integration Tests') { steps { echo 'Running integration tests...' } } } } } }
方式B:用脚本式节流块包裹整个流水线
如果是脚本式流水线,或者你需要更灵活的控制,可以用throttle指令把整个流水线逻辑包起来:
node('your-specific-slave-node') { // 限制同一节点上该作业最多1个实例运行 throttle(maxConcurrentPerNode: 1) { stage('Build') { echo 'Building...' } stage('Parallel Tests') { parallel { stage('Unit Tests') { echo 'Running unit tests...' } stage('Integration Tests') { echo 'Running integration tests...' } } } } }
2. 使用Lockable Resources插件(更灵活的资源锁定)
如果你的场景后续可能扩展到需要锁定其他共享资源(比如特定的测试环境),这个插件会更合适。你可以把目标节点配置成一个可锁定的资源,这样整个流水线运行前先抢占这个锁,同一时间只有一个流水线实例能使用该节点:
第一步:配置可锁定资源
在Jenkins全局配置中找到「Lockable Resources」,添加一个资源,比如命名为your-specific-node-lock,并关联到你的目标节点(或者不关联,直接在流水线里指定锁定该资源)。
第二步:在流水线中使用锁
pipeline { agent { node { label 'your-specific-slave-node' } } stages { stage('Acquire Node Lock') { steps { // 锁定资源,确保同一时间只有一个实例能进入后续步骤 lock(resource: 'your-specific-node-lock', inversePrecedence: true) { stage('Build') { echo 'Building...' } stage('Parallel Tests') { parallel { stage('Unit Tests') { echo 'Running unit tests...' } stage('Integration Tests') { echo 'Running integration tests...' } } } } } } } }
3. 作业级并发禁用(最简单的场景适配)
如果你的多分支作业所有分支都固定运行在同一个特定节点,并且你希望该作业的任何分支都不能并发执行,直接用流水线内置的disableConcurrentBuilds()选项就够了:
pipeline { agent { node { label 'your-specific-slave-node' } } options { disableConcurrentBuilds() } stages { // 你的流水线步骤... } }
这个方案的缺点是它是作业级别的限制,如果你后续需要让不同分支在不同节点并发,这个配置就不适用了。
最佳方案推荐
如果你习惯了自由风格里Throttling插件的节点级控制逻辑,**方案1(Throttle插件的全局配置)**是最优雅的选择——它直接对应你熟悉的「Maximum Concurrent Builds Per Node」配置,不需要额外学习新的插件逻辑,配置起来也最简洁。
内容的提问来源于stack exchange,提问作者Vitaly Karasik DevOps

