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

如何在Jenkins Pipeline中并行执行脚本以充分利用所有节点

Jenkins 节点动态分配优化实现

前置条件

  • 4个节点已绑定同一标签Autolabel,全部接入Jenkins服务器并处于运行状态
  • Jenkins Pipeline当前包含三个并行阶段:sanitylist1、sanitylist2、sanitylist3
  • 当前使用的Groovy脚本如下:
def sanitylist1 = script1.sh, script2.sh, script3.sh //All these are read from string parameter 
def sanitylist2 = script4.sh, script5.sh, script6.sh
def sanitylist3 = script7.sh, script8.sh, script9.sh

stage('Santiy tests') {
  parallel {

    stage('SanityList1') {
      options {
        timestamps()
        timeout(time: 6, unit: 'HOURS')
      }
      agent {
        node {
          label 'Autolabel'
          customWorkspace 'C:/git_repository'
        }
      }
      steps {
        script {
          for (i in sanitylist1) {
            echo "running : ${i}"
            bat "test.bat ${i}" //takes one script from sanitylist1 and replays
            sleep(10)
          }
        }
      }
    }

    stage('SanityList2') {
      options {
        timestamps()
        timeout(time: 6, unit: 'HOURS')
      }
      agent {
        node {
          label 'Autolabel'
          customWorkspace 'C:/git_repository'
        }
      }
      steps {
        script {
          for (i in sanitylist2) {
            echo "running : ${i}"
            bat "test.bat ${i}" //takes one script from sanitylist1 and replays
            sleep(10)
          }
        }
      }
    }

    stage('SanityList3') {
      options {
        timestamps()
        timeout(time: 6, unit: 'HOURS')
      }
      agent {
        node {
          label 'Autolabel'
          customWorkspace 'C:/git_repository'
        }
      }
      steps {
        script {
          for (i in sanitylist3) {
            echo "running : ${i}"
            bat "test.bat ${i}" //takes one script from sanitylist1 and replays
            sleep(10)
          }
        }
      }
    }
  } //parallel
} //parallel stage

需求

现有4个可用节点,但当前仅3个被占用,1个处于闲置状态。需实现动态分配闲置节点执行sanitylist1、sanitylist2或sanitylist3中的下一个脚本,提升执行效率,且无需新建SanityList4阶段。


实现方案

方案1:全局任务池动态并行(推荐)

打破原有阶段绑定,将所有脚本合并为一个任务池,让Jenkins自动根据可用节点数量分配任务,最大化利用4个节点资源。

修改后的脚本:

// 修正原脚本的数组定义(从字符串参数读取时需确保为数组格式)
def sanitylist1 = ['script1.sh', 'script2.sh', 'script3.sh']
def sanitylist2 = ['script4.sh', 'script5.sh', 'script6.sh']
def sanitylist3 = ['script7.sh', 'script8.sh', 'script9.sh']

// 合并所有脚本为统一任务池
def allSanityTasks = sanitylist1 + sanitylist2 + sanitylist3

stage('Sanity tests') {
  // 为每个脚本创建独立并行任务,Jenkins自动分配空闲节点
  parallel allSanityTasks.collectEntries { script ->
    ["Execute ${script}": {
      options {
        timestamps()
        timeout(time: 6, unit: 'HOURS')
      }
      agent {
        node {
          label 'Autolabel'
          customWorkspace 'C:/git_repository'
        }
      }
      steps {
        script {
          echo "running : ${script}"
          bat "test.bat ${script}"
          sleep(10)
        }
      }
    }]
  }
}

方案优势:

  • 完全释放节点资源,4个节点会同时执行不同脚本,直到所有任务完成
  • 无需维护固定阶段数量,脚本数量变化时自动适配
  • 保留原有的超时、时间戳、工作区配置

方案2:保留原阶段,动态申请节点

如果需要保留原有的sanitylist1/2/3阶段分组,可让每个脚本执行时单独申请空闲节点,避免整个阶段占用节点导致资源浪费。

修改后的脚本:

def sanitylist1 = ['script1.sh', 'script2.sh', 'script3.sh']
def sanitylist2 = ['script4.sh', 'script5.sh', 'script6.sh']
def sanitylist3 = ['script7.sh', 'script8.sh', 'script9.sh']

// 封装通用执行逻辑
def runSanityScript(String script) {
  node('Autolabel') {
    customWorkspace 'C:/git_repository'
    timestamps {
      timeout(time: 6, unit: 'HOURS') {
        echo "running : ${script}"
        bat "test.bat ${script}"
        sleep(10)
      }
    }
  }
}

stage('Sanity tests') {
  parallel {
    stage('SanityList1') {
      steps {
        script {
          sanitylist1.each { script ->
            runSanityScript(script)
          }
        }
      }
    }
    stage('SanityList2') {
      steps {
        script {
          sanitylist2.each { script ->
            runSanityScript(script)
          }
        }
      }
    }
    stage('SanityList3') {
      steps {
        script {
          sanitylist3.each { script ->
            runSanityScript(script)
          }
        }
      }
    }
  }
}

方案优势:

  • 保留原有阶段分组逻辑,便于查看各分组执行状态
  • 每个脚本执行完成后立即释放节点,其他阶段的待执行脚本可抢占空闲节点,避免资源闲置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:54:55