You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jenkins Pipeline在多节点同时运行相同任务集

解决Jenkins Pipeline多节点并行执行的问题

我懂你现在的困扰——原来的Pipeline是挨个串行处理每个VM节点,现在想改成所有节点同时跑,但直接把parallel和for循环混着用行不通。这是因为Jenkins的parallel语法要求传入一个键值对的映射集合,每个键对应一个要并行执行的任务闭包,咱们来改造你的脚本实现并行:

核心思路

先为每个节点创建一个包含其完整执行流程的闭包,把这些闭包整理成一个映射(键用节点名称保证唯一),最后把这个映射传给parallel块,这样所有节点就会同时启动各自的任务流了。

改造后的完整脚本

pipeline {
    agent any
    parameters {
        string(name: '_RNX_OS', description: '用「陇」分隔的节点名称列表')
        string(name: '_RNX_STAGES', description: '用「陇」分隔的测试/操作列表')
    }
    stages {
        stage('Parallel Node Execution') {
            steps {
                script {
                    // 分割参数得到节点列表和操作列表
                    def nodes = params._RNX_OS.split('陇')
                    def configs = params._RNX_STAGES.split('陇')
                    
                    // 构建并行任务映射
                    def parallelTasks = [:]
                    
                    for (String VMnode : nodes) {
                        // 创建局部变量捕获当前节点,避免闭包作用域引用问题
                        def currentNode = VMnode
                        parallelTasks["Node_${currentNode}"] = {
                            stage("Prepare environment for ${currentNode}"){
                                build job: "TA_StartVM", 
                                      parameters: [
                                          string(name: "_RNX_OS", value: currentNode), 
                                          string(name:"_RNX_SNAPSHOT", value:"Configured")
                                      ]
                            }
                            
                            for (String config : configs) {
                                switch (config) {
                                    case "Restart":
                                        stage("Restart VM ${currentNode}"){
                                            build job: 'TA_RestartVM', 
                                                  parameters: [string(name: "_RNX_OS", value: currentNode)]
                                        }
                                        break
                                    case ~/.*Start.*/:
                                        def param = config.split(':')
                                        def snapshot = param[1]
                                        stage("Start VM ${currentNode}"){
                                            build job: 'TA_StartVM', 
                                                  parameters: [
                                                      string(name: "_RNX_OS", value: currentNode), 
                                                      string(name:"_RNX_SNAPSHOT", value: snapshot)
                                                  ]
                                        }
                                        break
                                    case "Shutdown":
                                        stage("Shut down VM ${currentNode}"){
                                            build job: 'TA_ShutdownVM', 
                                                  parameters: [string(name: "_RNX_OS", value: currentNode)]
                                        }
                                        break
                                    case ~/.*Save.*/:
                                        def param = config.split(':')
                                        def snapshot = param[1]
                                        stage("Save VM Snapshot ${currentNode}"){
                                            build job: 'TA_SaveVMSnapshot', 
                                                  parameters: [
                                                      string(name: "_RNX_OS", value: currentNode), 
                                                      string(name:"_RNX_SNAPSHOT", value: snapshot)
                                                  ]
                                        }
                                        break
                                    default:
                                        stage("Run ${config} Test on ${currentNode}"){
                                            build job: 'TA_RunTest', 
                                                  parameters: [
                                                      [$class: 'LabelParameterValue', name: 'node', label: currentNode], 
                                                      string(name: "_RNX_TESTCONF", value: config), 
                                                      string(name: "_RNX_OS", value: currentNode)
                                                  ], 
                                                  propagate: false
                                        }
                                        break
                                }
                            }
                            
                            stage("Test Results Table for ${currentNode}"){
                                build job: 'TA_TestResultsTable',
                                      parameters: [[$class: 'LabelParameterValue', name: 'node', label: currentNode]], 
                                      propagate: false
                            }
                            
                            stage("Publish Test Results for ${currentNode}"){
                                build job: 'TA_CopyTestResults', propagate: false
                            }
                            
                            stage("Stop Slave ${currentNode}"){
                                build job: "TA_ShutdownVM", 
                                      parameters: [string(name: "_RNX_OS", value: currentNode)]
                            }
                        }
                    }
                    
                    // 执行所有并行任务
                    parallel parallelTasks
                }
            }
        }
    }
}

关键说明

  1. 闭包作用域处理:循环里创建了currentNode局部变量来捕获当前的VMnode,否则所有并行任务都会引用循环最后一个节点的值,这是Groovy闭包常见的坑。
  2. 并行任务映射:parallelTasks是一个Map,键用Node_${currentNode}保证每个并行任务的唯一性,值是包含该节点所有操作的闭包。
  3. 保留原有逻辑:所有原来的stage逻辑(启动VM、执行操作/测试、结果处理、停止VM)都完整保留,只是封装到了每个节点的闭包里。
  4. stage名称优化:给每个stage加上了节点名称后缀,这样在Jenkins界面上能清晰区分不同节点的执行进度。

这样改造后,所有节点会同时启动各自的完整流程,不用再等前一个节点执行完才开始下一个,完美解决你的并行需求。

内容的提问来源于stack exchange,提问作者ruva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:13:46