如何让Jenkins MultiJob等待指定节点空闲后并行执行子任务?
解决方案:实现MultiJob等待指定Windows节点空闲后并发执行子任务
当然可以实现!针对你的场景,我推荐两种可行方案,既能满足「等待Win node1/2/3全部空闲」的要求,又能保证三个子任务同时启动:
方案一:预构建Groovy脚本(最灵活可控)
因为你的MultiJob本身限制在Linux节点运行,所以可以在MultiJob的Pre-build Steps里添加一个「Execute system Groovy script」步骤,用代码主动检查目标Windows节点的状态,循环等待直到所有节点都空闲,再继续执行后续的子任务。
具体脚本示例
// 定义需要等待的目标节点名称(和Jenkins中节点名称完全一致,大小写敏感) def targetNodes = ["Win node1", "Win node2", "Win node3"] def checkInterval = 30 // 每次检查的间隔时间(秒) def maxWaitSeconds = 3600 // 最大等待时长(秒,避免无限等待) def startTime = System.currentTimeMillis() while (true) { def allNodesIdle = true targetNodes.each { nodeName -> def node = jenkins.model.Jenkins.instance.getNode(nodeName) if (!node) { throw new Exception("错误:节点 ${nodeName} 不存在,请检查名称是否正确!") } def computer = node.toComputer() // 判断节点是否空闲:在线状态 + 没有正在执行的任务 def isIdle = computer.isOnline() && computer.countBusy() == 0 if (!isIdle) { allNodesIdle = false println("节点 ${nodeName} 忙碌/离线,继续等待...") } } if (allNodesIdle) { println("所有目标Windows节点已空闲,即将并发启动子任务!") break } // 检查是否超过最大等待时长 def elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000 if (elapsedSeconds >= maxWaitSeconds) { throw new Exception("等待超时:已等待 ${maxWaitSeconds} 秒,仍有节点未空闲,终止构建!") } // 等待指定间隔后再次检查 sleep(checkInterval * 1000) }
注意事项
- 要确保Jenkins全局安全配置允许执行系统Groovy脚本(在「Manage Jenkins」→「Configure Global Security」中开启相关权限)
- 节点名称必须和Jenkins后台显示的完全一致,大小写不能错
- 可以根据你的实际需求调整
checkInterval(检查间隔)和maxWaitSeconds(最大等待时长)参数
方案二:结合MultiJob并发配置+节点空闲等待(更简洁)
如果你不想写脚本,也可以通过MultiJob的自带配置+子任务的节点等待规则来实现:
- 先在MultiJob的配置中,找到子任务列表的Advanced选项,勾选「Trigger builds concurrently」(并发触发子任务),确保三个子任务会同时启动
- 给每个子任务(n1、n2、n3)单独配置:进入子任务的配置页面,在「Build Environment」中勾选「Wait for node to be idle before starting」,并设置合理的等待超时时间
不过这种方式有个小局限:每个子任务只会等待自己的目标节点空闲,可能出现某一个子任务先启动,其他子任务还在等自己节点的情况,无法严格保证三个子任务完全同时启动。如果你的场景对“同时启动”的要求非常严格,方案一的预构建脚本会更靠谱。
内容的提问来源于stack exchange,提问作者VladoH
相关产品推荐
相关产品推荐

