在上一篇文章”Jenkins的Lockable Resource插件 - 1:基本使用”中,介绍了如何在Jenkins的Freestyle Job中使用Lockable Resource。
文章末尾提到一个问题:如果一个构建所需的资源已被其他正在运行的构建锁定,它将在队列中等待该资源可用。如果此时尝试再启动同一个构建加入等待队列,则会失败。本篇主要讨论这个问题的原因以及它的解决方法。
Jenkins和插件是开源项目。Jenkins的代码在https://github.com/jenkinsci/jenkins;Lockable Resource的代码在https://github.com/jenkinsci/lockable-resources-plugin。
大致查看了这两个项目的目录结构,浏览了几个文件,根据数据结构进行大胆地推测:
实验:当DEMO_JOB#96
正在运行时,再次点击Build Now按钮3次。Build Queue中只会出现一个构建对象。当将鼠标指向队列中的对象时,可以查看其 actions
、阻塞原因和等待时间。
原因:在使用Lockable Resource插件时,加入Jenkins的队列的多个构建对象被合并为一个对象,而这个对象具有多个action。(一个源文件都没完整读过,结论纯属猜测,千万别信)
实验:创建了一个参数化的 Jenkins 作业(添加String Parameter:PARM
),并多次触发构建请求,每次请求都使用不同的参数(如不同的字符串:0
、1
、2
……)。实验的目标是观察 Jenkins 的队列行为:Jenkins 无法将参数不同的构建请求合并为队列中的一个单一构建对象,因此每次点击 Build Now,queue 中都会增加一个构建对象。
启动6个构建:PARAM依次为[0, 0, 1, 1, 2, 3]
#103: PARAM = 0 (RUNNING)
#104: PARAM = 0 (PENDING)
两个PARAM = 1的构建被合并为1个#105
#105: PARAM = 1 (PENDING)
两个PARAM = 2的构建被合并为1个
#106: PARAM = 2 (PENDING)
每次为 Jenkins Job 手动填写不同的参数值是一项繁琐且容易出错的任务。为了解决这个问题,我们可以设计一个自动化的方法,使每次构建都能自动添加一个唯一的参数值。以下是实现这个目标的步骤:
TIMESTAMP
。return [java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))]
。TIMESTAMP
值,点击Build按钮后,页面跳转并刷新,TIMESTAMP
则自动更新。解决了这个问题后,我们下一篇将会介绍一些更复杂、更贴近实际的用法,敬请期待。
如果你的Jenkins已经采用了pipeline,则可以通过代码掌控一切。但是有些项目和同事仍在使用祖传的的Freestyle类型的Job,因此才会有这些实验和本文的内容,探索一下也算有趣。