如何在Jenkins同个任务的多次构建之间共享少量数据?
方案1:使用Lockable Resources插件实现实例池调度(无需自行维护共享数据)
这个方案适配你的场景不需要额外开发数据持久化逻辑,是成本最低的稳定方案:
- 首先在Jenkins系统配置的「可锁定资源」板块,把你所有的X实例逐个注册为独立的可锁定资源,统一打上
X-resource标签方便批量调度 - 流水线的集成阶段直接调用
lock步骤申请可用资源,代码示例如下:
lock(label: 'X-resource', quantity: 1, variable: 'SELECTED_X_INSTANCE') { echo "当前选中的X实例为:${SELECTED_X_INSTANCE}" // 执行订阅X、测试、取消订阅的原有逻辑 // 测试完成后增加固定冷却时长,比如5分钟确保实例状态恢复 sleep time: 5, unit: 'MINUTES' }
- 该方案完全由Jenkins原生维护资源占用状态,就算构建中途异常退出,锁也会自动释放,不会出现资源死锁,也不需要你手动维护实例的使用时间映射表。
方案2:控制器节点持久化文件存储共享数据
如果你需要自定义更灵活的调度逻辑,可以用Jenkins控制器的本地文件存共享数据:
- 先在Jenkins控制器节点创建专用的存储目录,比如
/var/jenkins_home/shared-data/x-status/,给Jenkins运行用户开放读写权限 - 操作共享数据前先加全局锁避免并发读写冲突,代码示例如下:
lock('x-instance-status-lock') { def statusPath = '/var/jenkins_home/shared-data/x-status/status.json' def instanceStatus = [:] // 读取已有状态,文件不存在则初始化 if (fileExists(statusPath)) { instanceStatus = readJSON file: statusPath } else { ['x-1', 'x-2', 'x-3'].each { id -> instanceStatus[id] = 0 } } // 筛选冷却超过5分钟的可用实例 def currentTs = new Date().getTime() def availableInstances = instanceStatus.entrySet().findAll { currentTs - it.value > 5 * 60 * 1000 }.collect { it.key } // 选中实例后先更新时间戳写回文件,再执行后续逻辑 def selected = availableInstances[0] instanceStatus[selected] = currentTs writeJSON file: statusPath, json: instanceStatus // 后续执行订阅、测试逻辑 }
- 该方案兼容构建失败场景:选中实例后立刻更新时间戳,哪怕后续构建异常退出,该实例的冷却时间也会正常计算,不会被后续构建提前调用。
方案3:任务动态属性存储共享数据
如果不想在控制器节点新增文件,也可以把共享数据直接存在Jenkins任务的属性中:
lock('x-instance-status-lock') { def job = Jenkins.instance.getItemByFullName(env.JOB_NAME) // 读取任务属性中存储的实例状态 def instanceStatus = job.properties.get('xInstanceStatus') ? new groovy.json.JsonSlurper().parseText(job.properties.get('xInstanceStatus').value) : [:] // 筛选实例、更新时间戳的逻辑和方案2一致 // 更新完成后把状态写回任务属性 job.addProperty(new hudson.model.ParametersAction([ new hudson.model.StringParameterValue('xInstanceStatus', groovy.json.JsonOutput.toJson(instanceStatus)) ])) }
- 该方案需要给流水线开通脚本安全权限,允许访问Jenkins内置实例API。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

