如何在Jenkins脚本式流水线中重试失败构建或未触发的定时任务?
Jenkins脚本式流水线实现失败重试及定时任务补偿方案
一、脚本式流水线基础失败重试实现
脚本式流水线没有声明式的retry语法糖,但可以通过两种方式实现失败重试:
1. 使用内置retry步骤
直接用Jenkins提供的内置步骤,指定重试次数,将可能失败的代码块包裹其中:
// 最多重试3次,只要某次执行成功就继续后续流程 retry(3) { // 替换为你的实际构建步骤,例如编译、测试等 sh 'mvn clean install' }
2. 自定义重试逻辑(灵活控制)
如果需要针对特定错误类型重试、添加重试间隔,可通过循环+try-catch实现:
def maxRetries = 3 def retryCount = 0 def buildSuccess = false while (!buildSuccess && retryCount < maxRetries) { try { // 执行核心构建任务 sh 'mvn clean install' buildSuccess = true } catch (Exception e) { retryCount++ echo "构建失败,第${retryCount}次重试中..." if (retryCount >= maxRetries) { throw e // 达到最大重试次数,抛出异常终止流水线 } sleep 30 // 重试前等待30秒,可根据需求调整 } }
二、针对「上一次构建失败」的重试触发
在流水线启动时检查历史构建状态,若上一次构建失败则自动执行重试逻辑:
// 获取当前任务的上一次构建记录 def lastBuild = currentBuild.previousBuild if (lastBuild && lastBuild.result == 'FAILURE') { echo "检测到上一次构建失败,启动重试流程(最多3次)" retry(3) { // 核心构建步骤 echo "执行构建:参数1=${params.optional_param1}, 参数2=${params.optional_param2}, 参数3=${params.optional_param3}" sh 'mvn clean install' } } else { echo "上一次构建成功或无历史记录,执行正常构建流程" // 核心构建步骤 echo "执行构建:参数1=${params.optional_param1}, 参数2=${params.optional_param2}, 参数3=${params.optional_param3}" sh 'mvn clean install' }
三、针对「定时任务未触发」的补偿方案
定时任务未触发可能因Jenkins离线、cron配置错误导致,可通过监控流水线实现补偿:
监控流水线示例
创建独立的监控流水线,定时检查目标任务的触发记录,若发现遗漏则触发补偿构建:
properties([pipelineTriggers([cron('H/15 * * * *')])]) // 每15分钟检查一次 def targetJobName = "你的目标流水线名称" def targetCron = "0 0 * * *" // 目标任务的cron表达式 def job = Jenkins.instance.getItem(targetJobName) def lastBuildTime = job.lastBuild?.getTime() // 计算预期的上一次触发时间 def cronParser = new hudson.triggers.TimerTrigger.CronParser(targetCron) def expectedLastTrigger = cronParser.getPreviousTime(new Date()) // 若超过预期触发时间30分钟仍未构建,判定为未触发 if (!lastBuildTime || (new Date().getTime() - expectedLastTrigger.getTime() > 30 * 60 * 1000)) { echo "发现定时任务未触发,启动补偿构建..." job.scheduleBuild2(0, new Cause.UserIdCause()) } else { echo "定时任务触发正常,无需补偿" }
四、整合你的现有配置的完整示例
将重试逻辑与你提供的参数、定时触发器配置结合:
properties([ parameters([ string(defaultValue: "", description: 'optional_param1', name: "optional_param1"), string(defaultValue: "", description: 'optional_param2', name: "optional_param2"), string(defaultValue: "", description: 'optional_param3', name: "optional_param3"), ]), pipelineTriggers([cron(cronExpression)]), ]) // 检查上一次构建状态 def lastBuild = currentBuild.previousBuild def shouldRetry = lastBuild ? (lastBuild.result == 'FAILURE') : false def maxRetries = 3 if (shouldRetry) { echo "上一次构建失败,启动重试(最多${maxRetries}次)" retry(maxRetries) { // 替换为你的实际构建逻辑 echo "构建参数:param1=${params.optional_param1}, param2=${params.optional_param2}, param3=${params.optional_param3}" sh 'mvn clean install' } } else { echo "执行正常构建流程" echo "构建参数:param1=${params.optional_param1}, param2=${params.optional_param2}, param3=${params.optional_param3}" sh 'mvn clean install' }
注意事项
- 权限:访问
Jenkins.instance需要流水线具备相应权限,若环境受限,可改用currentBuild.previousBuild获取历史状态。 - 避免无限循环:务必设置最大重试次数,防止流水线陷入死循环。
- 定时补偿阈值:根据你的cron频率调整时间阈值,避免误判。
内容的提问来源于stack exchange,提问作者Mr. E
相关产品推荐
相关产品推荐

