Jenkins多流水线并发调用单实例流水线的执行异常解决咨询
Jenkins多父流水线调用非并发子流水线时复用构建编号的问题解决
环境配置
- Jenkins部署在EC2实例,采用主节点+1个从节点架构
- 从节点配置15个执行器(executors)
- 存在一个Android模块构建流水线:接收父流水线传入的变量,已启用「Do not allow concurrent builds(不允许并发构建)」选项
- 存在10个Android .apk构建流水线:支持手动触发,均包含调用上述Android模块构建流水线的阶段
问题现象
同时触发8条.apk构建流水线时,因从节点执行器充足,所有父流水线可同时启动。但进入调用Android模块流水线的阶段时:
- 第一条父流水线会执行子流水线,其余7条进入等待状态
- 第一条子流水线执行完成后,剩余7条父流水线会同时调用子流水线且复用同一个构建编号,导致子流水线无法根据不同父流水线传入的变量正常执行,不符合预期。
需求:让剩余7条父流水线依次调用子流水线,确保每条子流水线都能使用对应父流水线传入的变量独立执行。
解决方案
1. 给子流水线添加唯一标识参数
Jenkins默认会对参数完全相同的子流水线构建请求进行合并复用,因此需要给子流水线添加一个唯一标识参数(比如父流水线的构建编号),让每个调用请求都具备唯一的参数组合,避免被合并。
操作步骤:
- 在Android模块构建流水线的参数中新增一个字符串类型参数(例如
PARENT_BUILD_NUMBER) - 保持子流水线的「Do not allow concurrent builds」选项开启
2. 父流水线调用时传入唯一参数
在父流水线的build步骤中,明确传入当前父流水线的构建编号作为唯一参数,示例Groovy代码:
build( job: 'Android模块构建流水线', parameters: [ // 原业务参数,根据实际需求传入 string(name: 'ANDROID_MODULE', value: "${MODULE_NAME}"), // 父流水线唯一标识,确保每个调用的参数组合唯一 string(name: 'PARENT_BUILD_NUMBER', value: "${currentBuild.number}") ], wait: true, propagate: true )
这样每个父流水线调用的子流水线都会被Jenkins视为独立的构建任务,按顺序排队执行,不会复用之前的构建编号。
3. 检查子流水线的触发配置
- 确保子流水线未开启「Build after other projects are built」等自动触发规则,避免意外的构建合并
- 确认子流水线的「Advanced Project Options」中,未勾选「Allow upstream projects to trigger even if the build is already running」选项
4. 使用锁插件强制串行调用(可选)
如果上述方法仍有问题,可以使用Lockable Resources Plugin,在父流水线调用子流水线的阶段添加全局锁,确保同一时间只有一个父流水线在调用子流水线:
// 先安装Lockable Resources Plugin,然后在Jenkins全局配置中添加名为"AndroidModuleBuildLock"的资源 lock(resource: 'AndroidModuleBuildLock') { build( job: 'Android模块构建流水线', parameters: [ string(name: 'ANDROID_MODULE', value: "${MODULE_NAME}"), string(name: 'PARENT_BUILD_NUMBER', value: "${currentBuild.number}") ] ) }
这种方式从父流水线层面保证调用的串行性,彻底避免子流水线的构建复用问题。
内容的提问来源于stack exchange,提问作者Twisted_sister
相关产品推荐
相关产品推荐

