Jenkins - Parallel 并行执行

Jenkins - Parallel 并行执行

  • 引言
  • Jenkins Parallel 基本用法
  • Jenkins Prallel 启动多个其他 Job
  • Jenkins Parallel Retry

引言

日常执行测试用例,为了缩减执行时间,提高工作效率,可以从以下两个方面进行改进。

  • 代码层面:用多进程并发执行代替单进程串行执行,更多细节请参考《Python 多线程和多进程并发执行》
  • Jenkins 层面:我们可以将测试用例拆分成多个 Job,然后并行执行这些 Job。

今天主要了解一下 Jenkins 并行多个 Job 执行。

Jenkins Parallel 基本用法

在 Jenkins pipeline 中,parallel 关键字用于并行执行多个步骤。这可以显著减少构建时间,特别是当你有多个独立的任务需要完成时。

下面这个脚本定义了一个 Jenkins pipeline,其中包含一个 Parallel Jobs 阶段,使用 parallel 块来定义并行执行的多个子阶段,该阶段下有三个并行的子阶段(Job 1、Job 2 和 Job 3)。每个子阶段包含具体的步骤,例如 echo 和 sh 命令。

pipeline {agent anystages {stage('Parallel Jobs') {parallel {stage('Job 1') {steps {echo 'Running Job 1'// 在这里添加 Job 1 的具体执行步骤sh 'echo "Job 1 executed"'}}stage('Job 2') {steps {echo 'Running Job 2'// 在这里添加 Job 2 的具体执行步骤sh 'echo "Job 2 executed"'}}stage('Job 3') {steps {echo 'Running Job 3'// 在这里添加 Job 3 的具体执行步骤sh 'echo "Job 3 executed"'}}}}}
}

我们来看一下运行效果:Job 1、Job 2 和 Job 3 是同进运行的

17:24:14  [Pipeline] {
17:24:14  [Pipeline] stage
17:24:14  [Pipeline] { (Parallel Jobs)
17:24:14  [Pipeline] parallel
17:24:14  [Pipeline] { (Branch: Job 1)
17:24:14  [Pipeline] { (Branch: Job 2)
17:24:14  [Pipeline] { (Branch: Job 3)
17:24:14  [Pipeline] stage
17:24:14  [Pipeline] { (Job 1)
17:24:14  [Pipeline] stage
17:24:14  [Pipeline] { (Job 2)
17:24:14  [Pipeline] stage
17:24:14  [Pipeline] { (Job 3)
17:24:14  [Pipeline] echo
17:24:14  Running Job 1
17:24:14  [Pipeline] sh
17:24:14  [Pipeline] echo
17:24:14  Running Job 2
17:24:14  [Pipeline] sh
17:24:14  [Pipeline] echo
17:24:14  Running Job 3
17:24:14  [Pipeline] sh
17:24:14  + echo Job 1 executed
17:24:14  Job 1 executed
17:24:14  [Pipeline] }
17:24:14  + echo Job 2 executed
17:24:14  Job 2 executed
17:24:14  [Pipeline] // stage
17:24:14  [Pipeline] }
17:24:14  + echo Job 3 executed
17:24:14  Job 3 executed
17:24:14  [Pipeline] }
17:24:14  [Pipeline] // stage
17:24:14  [Pipeline] }
17:24:14  [Pipeline] }
17:24:15  [Pipeline] // stage
17:24:15  [Pipeline] }
17:24:15  [Pipeline] // parallel
17:24:15  [Pipeline] }
17:24:15  [Pipeline] // stage
17:24:15  [Pipeline] }
17:24:15  [Pipeline] // node
17:24:15  [Pipeline] End of Pipeline
17:24:15  Finished: SUCCESS

Jenkins Prallel 启动多个其他 Job

上在举例中 3 个 Job 只是执行一些基础脚本,现实测试过程中,是需要并行执行多个其它 Job 的,并且需要传参,获取执行结果等等。
下面定义一个 Jenkins pipeline,主 job 传参给子 job,并行执行三个子 job,每个子阶段使用 build 步骤触发其他 Jenkins job (Testing_1,Testing_2,'Testing_3),并使用 wait: false 参数使其异步执行,最后将子 job 的信息传给 report job,发邮件汇总测试结果。

propagate: false 表示即使这个 job 失败,也不会导致整个 pipeline 失败。如果你希望 job 失败时 pipeline 也失败,可以将其设置为 true。

#!groovy
pipeline {options {buildDiscarder(logRotator(numToKeepStr: '50', daysToKeepStr: '100'))}agent { label "ubuntu" }parameters {choice(name: 'branch', choices: ["main","feature"])choice(name: "Environment", choices: ["cert", "dev", "prod"])string(name: 'project_name', defaultValue: 'Cert XXX', description: 'example : Cert XXX, Prod XXX')choice(name: "sheet_name", choices: ["sheet 1", "sheet 2", "sheet 3"])choice(name: "action", choices: ["action 1","action 2", "action 3"])string(name: 'email_list', defaultValue: 'aaa@bbb.com',description: 'example : aaa@bbb.com, bbb@bbb.com')booleanParam(name: 'SAVE_TEST_RESULT_TO_HISTORY', defaultValue: true, description: 'Would you like to save test result to history?') }stages {stage('Parallel Jobs') {parallel {stage('Testing 1') {agent { label "ubuntu" }steps {script {def job_1 = build job: 'Testing_1',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]    job_1_project_name = job_1.getFullProjectName()job_1_build_num = job_1.getNumber()}}}stage('Testing_2') {agent { label "ubuntu" }steps {script {def job_2 = build job: 'Testing_2',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]job_2_project_name = job_2.getFullProjectName()job_2_build_num = job_2.getNumber()}}}stage('Testing_3') {agent { label "ubuntu" }steps {script {def job_3 = build job: 'Testing_3',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]job_3_project_name = job_3.getFullProjectName()job_3_build_num = job_3.getNumber()                 }}}}}}post {always{build job: 'Report',parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'project_name', value: "${params.project_name}"),string(name: 'job_1_project_name', value: "${job_1_project_name}"),string(name: 'job_1_build_num', value: "${job_1_build_num}"),string(name: 'job_2_project_name', value: "${job_2_project_name}"),string(name: 'job_2_build_num', value: "${job_2_build_num}"),string(name: 'job_3_project_name', value: "${job_3_project_name}"),string(name: 'job_3_build_num', value: "${job_3_build_num}"),string(name: 'email_list', value: "${params.email_list}"),booleanParam(name: 'SAVE_TEST_RESULT_TO_HISTORY', value: "${params.SAVE_TEST_RESULT_TO_HISTORY}")]}  }
}

Jenkins Parallel Retry

上面例子的 Jenkins pipeline,并行执行多个 Job,也会有遇到一些异常,比如某一个子 job 因为环境问题导致失败,尽管不会中断整个 pipeline job,但是会影响整个 pipeline 的执行结果,只得到部分执行结果。文章《Jenkins - Pipeline Retry》只是简单的 job retry,对于并行执行其它 jenkins job 不太适合。
对于并行执行其它 jenkins job,retry 是必须要加上的,此外只要 job 执行失败必须得抛出 error 手动抛出异常,触发重试,不然不会 retry 重试。

所以将上面的 jenkins pipeline 脚本改一下,加上 retry
parallel 块:并行执行多个 job (Testing_1,Testing_2,Testing_3),每个 job 独立处理其失败和重试逻辑。
retry 步骤:retry(3) 表示在一个 job 失败时最多重试 3 次。
error 步骤:在捕获的异常中使用 error 步骤手动抛出异常,触发重试。

#!groovy
pipeline {options {buildDiscarder(logRotator(numToKeepStr: '50', daysToKeepStr: '100'))}agent { label "ubuntu" }parameters {choice(name: 'branch', choices: ["main","feature"])choice(name: "Environment", choices: ["cert", "dev", "prod"])string(name: 'project_name', defaultValue: 'Cert XXX', description: 'example : Cert XXX, Prod XXX')choice(name: "sheet_name", choices: ["sheet 1", "sheet 2", "sheet 3"])choice(name: "action", choices: ["action 1","action 2", "action 3"])string(name: 'email_list', defaultValue: 'aaa@bbb.com',description: 'example : aaa@bbb.com, bbb@bbb.com')booleanParam(name: 'SAVE_TEST_RESULT_TO_HISTORY', defaultValue: true, description: 'Would you like to save test result to history?') }stages {stage('Parallel Jobs') {parallel {stage('Testing 1') {agent { label "ubuntu" }steps {retry(3) {script {def job_1 = build job: 'Testing_1',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]    job_1_project_name = job_1.getFullProjectName()job_1_build_num = job_1.getNumber()if (job_1.result != 'SUCCESS') {error "Job Content_Testing_1 failed with result: ${job_1.result}"}}}}}stage('Testing_2') {agent { label "ubuntu" }steps {retry(3) {script {def job_2 = build job: 'Testing_2',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]job_2_project_name = job_2.getFullProjectName()job_2_build_num = job_2.getNumber()if (job_2.result != 'SUCCESS') {error "Job Testing_2 failed with result: ${job_2.result}"} }}}}stage('Testing_3') {agent { label "ubuntu" }steps {retry(3) {script {def job_3 = build job: 'Testing_3',propagate: false,wait: true,parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'Environment', value: "${params.Environment}"),string(name: "sheet_name", value: "${params.sheet_name}"),string(name: "action", value: "${params.action}")]job_3_project_name = job_3.getFullProjectName()job_3_build_num = job_3.getNumber()if (job_3.result != 'SUCCESS') {error "Job Testing_3 failed with result: ${job_3.result}"}}}}}}}}post {always{build job: 'Report',parameters: [string(name: 'branch', value: "${params.branch}"),string(name: 'project_name', value: "${params.project_name}"),string(name: 'job_1_project_name', value: "${job_1_project_name}"),string(name: 'job_1_build_num', value: "${job_1_build_num}"),string(name: 'job_2_project_name', value: "${job_2_project_name}"),string(name: 'job_2_build_num', value: "${job_2_build_num}"),string(name: 'job_3_project_name', value: "${job_3_project_name}"),string(name: 'job_3_build_num', value: "${job_3_build_num}"),string(name: 'email_list', value: "${params.email_list}"),booleanParam(name: 'SAVE_TEST_RESULT_TO_HISTORY', value: "${params.SAVE_TEST_RESULT_TO_HISTORY}")]}  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

15 试用期,转正时我们要考察什么?

上一讲,我点出了“找人并不等于盲目加人”,你既要明确业务现状与团队需求,更要做好面试甄别,做出最优决定。那么当你找到人之后,是不是就可以高枕无忧了呢?并不是。 因为最终目的并非招聘,而是…

基于安卓的虫害识别软件设计--(2)模型性能可视化|混淆矩阵、热力图

1.混淆矩阵(Confusion Matrix) 1.1基础理论 (1)在机器学习、深度学习领域中,混淆矩阵常用于监督学习,匹配矩阵常用于无监督学习。主要用来比较分类结果和实际预测值。 (2)图中表达…

FPGA代码移植案例分析:Tcl Scripts后提示找不到 vo 文件,Supra软件报错

FPGA代码移植案例分析:Tcl Scripts后提示找不到 vo 文件,Supra软件报错 客户工程师已经运行Tcl Scripts,正常没出错就会产生这个vo文件。工程师试了两次 运行之后点的next的,还是出现同样的错误。 建议客户在原quartus工程里重新…

LabVIEW如何确保步进电机的长期稳定运行

步进电机因其良好的定位精度和控制性,在自动化设备中得到了广泛应用。然而,长期稳定运行对于任何电机系统都是一个重要的挑战。LabVIEW作为一款强大的图形化编程语言,通过其灵活的控制算法和实时监控能力,为步进电机的稳定运行提供…

探索 Vue Devtools 4.0 的新世界!

大家好,我是前端宝哥。Vue Devtools 4.0 版本带来了一系列激动人心的新特性和改进,让我们一起来探索这些更新亮点! 宝哥省流版: 🛠 直接编辑组件数据,实时预览变更效果。⚙️ 快速编辑功能,一键…

Python 基于机器学习模型的车牌检测和识别系统 有GUI界面 【含Python源码 MX_004期】

一、系统介绍 车牌的检测和识别技术在现代社会中的应用场景可谓十分广泛,不仅涉及交通管理领域,还延伸至社区安保等多个方面。例如,在交通违章管理中,通过车牌追踪可以有效追踪违章车辆,维护交通秩序;在小区…

如何高效管理团队任务?强大的在线管理团队多任务的神器-YesDev

任务是最小的工作项,工时是可以对研发产能进行量化。 一员工工时 工作组工时登记配置 针对于工作组,你可以开启/关闭工时登记。关闭工作组的工时登记后,整个工作组将取消工时登记,重新开启后恢复。 在同一个工作组内&#xff0c…

碰撞检测技术在AI中的重要作用

引言: 随着人工智能技术的不断发展,AI已经渗透到我们生活的方方面面。在游戏、机器人、虚拟现实等领域中,碰撞检测技术扮演着至关重要的角色。本文将探讨碰撞检测技术在AI中的作用,以及如何利用这项技术来改善AI系统的性能和用户体…

6,串口编程———通过串口助手发送数据,控制led亮灭

//功能:串口助手每次发送数据格式:0000& // 第二个字节控制LED1亮灭 // 第三个字节控制LED2亮灭 // 第四个字节控制LED3亮灭 // 第无个字节控制LED4亮灭 //要求:代码能够一直运行,能够接收多字节数据 上节讲了串口的基本…

宁波财经学院程序设计补修单链表

2024年6月2日 #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 typedef struct Node { int data; struct Node* next; } Node; // 尾插函数 void append(Node** head_ref, int new_data) { // 1. 分配新节点&#xff0c;并设置其数据…

数学问题求解能力提升:ChatGLM-Math模型的自我批评管道

大型语言模型&#xff08;LLMs&#xff09;在处理语言任务上取得了巨大进步&#xff0c;但在解决需要数学推理的实际问题时仍面临挑战。这些挑战包括数学问题的复杂性、需要高度准确性和逻辑一致性的解答、缺乏深入的数学领域知识&#xff0c;以及现有模型对反馈的依赖性&#…

【Docker】学习笔记(超万字图文整理)

前言 再此感谢黑马程序员提供的Docker课程&#xff01; 什么是Docker&#xff1f;看这一篇干货文章就够了&#xff01; UPD: 补充更新微服务集群、Docker镜像仓库部分内容 所有笔记、生活分享首发于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#…

k8s集群修改apiserver的ip地址

有时候由于服务器的调整&#xff0c;导致ip的的变化&#xff0c;k8s集群的api大管家的ip变动会导致kubectl的接口都无法正常使用&#xff0c;这是只需要将k8s主节点配置文件的ip替换即可。 例如无需要将原来的192.168.146.202的ip替换成192.168.85.202&#xff0c;执行一下操作…

后端开发技术栈选择指南

在软件开发领域&#xff0c;后端开发是构建应用程序的服务器端逻辑、数据库、API和业务规则的核心部分。选择合适的后端技术栈对于项目的成功至关重要。本文将详细介绍当前流行的几种后端开发技术栈&#xff0c;并探讨它们的优势、适用场景以及如何根据项目需求进行选择。 Jav…

全文检索-ElasticSearch

1.基本概念 1.Index索引 动词&#xff1a;相当于MySQL中的insert&#xff1b; 名词&#xff1a;相当于MySQL中的DataBase&#xff1b; 2.Type&#xff08;类型&#xff09; 在Index&#xff08;索引&#xff09;中&#xff0c;可以定义一个或多个类型 类似于MySQL中的Tab…

Win键的快捷键

查找设置 win开始菜单win Q搜索窗口win E文件资源管理器win R运行窗口win A操作中心win I 设置中心 win num打开任务栏的第num窗口win V剪切板 录制 win G录制工具(Esc退出) 多桌面工作 win Ctrl D创建桌面win Ctrl F4关闭桌面win Ctrl 左右方向键切换桌面…

Mysql | select语句导入csv后再导入excel表格

需求 从mysql数据库中导出数据到excel 解决方案 sql导出csv文件 sql SELECT col1,col2 FROM tab_01 WHERE col3 xxx INTO OUTFILE /tmp/result.csv FIELDS TERMINATED BY , ENCLOSED BY " LINES TERMINATED BY \n;csv文件导出excel文件 1、【数据】-【导入数据】 …

C和c++头文件库

C语言和c里面都有哪些我们常会用到的头文件呢&#xff1f;要了解每种头文件库的作用&#xff0c;才能更好的写代码。 1.c语言 C语言中的头文件&#xff08;Header Files&#xff09;是包含函数声明、宏定义、数据类型和常量定义的文件&#xff0c;通常具有.h扩展名。头文件的…

【QT】如何将printf打印输出至窗体

在Qt中&#xff0c;通常不推荐使用printf函数来输出信息到窗体&#xff0c;因为Qt有自己的信号和槽机制以及日志系统来处理输出和调试信息。不过&#xff0c;如果你确实需要将printf的输出重定向到Qt的窗体&#xff0c;你可以通过重定向标准输出来实现。 以下是一个简单的例子…

【计算机毕设】基于SpringBoot的教学资源库设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个基于SpringBoot的教学资源库系统&#xff0c;以便教师和学生能够方便地存储、分享和查找各种教学资源。具体目标包括&…