如何防止某些 Jenkins 作业同时运行?

71

我有几个使用共享资源(数据库)的工作,有时候会导致构建失败,因为这些工作可能同时运行。

例如,对于工作A到E,是否有一种方式可以指定A和C不应该同时运行

除了上述资源之外,构建是相互独立的(没有上游/下游关系等)。

“蛮力”方法是将执行者的数量限制为一个,但如果大多数工作可以同时执行且构建服务器上没有计算资源缺乏,那显然不是理想的解决方案。


看起来这个插件已经被列入不推荐使用的名单了 :( - John T Dyer
哪个插件在弃用列表中? - marc.guenther
1
@marc.guenther:John的评论与Locks and Latches插件有关,该插件在pwan的回答中提到。它在这里被建议弃用,但除此之外,我没有看到任何迹象表明它会消失。因此,我想您可以使用“锁定和闩锁”或“限制并发构建”来实现此目的。 - Jonik
3
避免使用锁定和锁插件,它已被列入废弃清单中。如果您在作业等待获取锁时手动中断作业,则该作业将不再运行,直到Jenkins主服务器重新启动。“限制并发构建”插件是一个更好的选择,它不会危及您的Jenkins安装。 - Fabian Ritzmann
6个回答

46

目前有两种方法可以实现这个:


2
由于某些原因,仅使用一个执行器的简单方法对我不起作用。我将其配置为1,4天后有人报告说有2个正在运行,而配置显示:最大值=1。 - sorin
有人知道是否可以使用节流并发构建来限制两个流水线的速度,但同时允许其中一个流水线并发执行其自己的作业吗?例如,我有一个A流水线和一个B流水线,我正在运行A,而B将无法运行,因为A有一些作业正在运行。如果有任何A在运行,则希望能够同时运行N个A作业,而不运行B中的任何作业。 - Marc43

14

3
谢谢,我已经让它工作了!快速参考:1)在“管理Jenkins -> 配置系统 -> 锁定”中定义锁定(我使用了共享数据库的名称);2)将相关作业设置为使用锁定:配置 -> 构建环境 -> 锁定 - Jonik
我的问题似乎确实归结为与旧问题相同的事情。但我会认为这个问题更清晰(问题主体中没有基本无关的大段文字,也没有误导性的标签)... - Jonik
1
提醒一下,有时候多个任务会同时获得锁。您可以通过限制该节点上执行器的数量来避免这种情况。 - Feasoron
8
正如 @John T Dyer 指出的那样,锁定和闩锁插件已被列入 拟议插件弃用清单。阅读该页面上的评论,似乎 限制并发构建插件 可以成为一个可行的替代品。 - Jonik
1
对于Jenkins:限制并发构建插件 - Tuukka Mustonen

6

这是一个老问题,但该主题仍然可能相关,特别是在Jenkins上运行应用程序测试时。

Lockable Resources Plugin 允许您定义可由构建使用的可锁定资源。如果您的构建需要一个资源,它将锁定该资源。如果第二个构建需要相同的资源(已经被锁定),则它将排队等待资源得到释放。

虽然文档中使用计算机或打印机作为可锁定资源的示例,但上面的数据库示例也应该可以工作。

与2012年答案中提到的Locks and Latches Plugin相反,这个插件似乎目前正在维护(当前 ~2016)。


2
请查看于2012年11月首次发布的Jenkins插件External Resource Dispatcher,该(相对)较新的插件似乎正好涵盖了这种用例。

1
它充满了漏洞(我不得不修改源代码才能使其半正常工作),并且不再与最新的Jenkins兼容。除此之外,它本来就是我想要的东西 :-) - Cameron

0

注意:您不需要为从节点准备物理或虚拟硬件,您可以设置在主服务器上运行的“从节点”。

管理Jenkins > 管理节点 > 新建节点

并创建一个“愚蠢的从节点”,每个从节点都有自己的根目录。

创建一些从节点,在服务器启动时执行它们,然后您基本上创建了执行器池。

例如,您可能会有...

db - 在您的情况下只有一个执行器。 编译 - 根据硬件或CPU数量限制。 脚本 - 为Jenkins擅长处理的所有小任务创建多个执行器。


0

这是一个旧问题,我不能确定它是否适用于您的应用程序,因为您没有提及应用程序的详细信息。但是,我想添加一下我们在Rails应用程序测试套件中处理此问题的方式。

我们应用程序的数据库配置(database.yml)不在源代码库中。相反,它位于运行我们Jenkins实例的VM上的/var/lib/configs/uniquing_database.yml中。

我们构建过程的其中一步涉及将此配置文件复制到项目工作区:

cp /var/lib/jenkins/configs/myapp_unique_database.yml config/database.yml

而该配置会考虑Jenkins在环境中公开的工作区和构建编号信息,以便为该作业及其特定执行创建一个唯一命名的数据库:

test:
  adapter: postgresql
  encoding: unicode
  host: 127.0.0.1
  port: 5432
  database: myapp_test<%= ENV['JOB_NAME'].split('/').last %><%= ENV['BUILD_NUMBER'] %>

我们的其余构建过程并不知道或关心它正在运行在一个不同的数据库中。最后,在我们的构建结束时,我们确保删除该数据库,以便我们不会有一堆测试数据库污染文件系统:

RAILS_ENV=test bundle exec rake db:drop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接