Par*_*thi 6 parallel-processing jenkins jenkins-pipeline
我正在执行并行步骤 -
stages {
stage ('Parallel build LEVEL 1 - A,B,C ...') {
steps{
parallel (
"Build A": {
node('Build_Server_Stack') {
buildAndArchive(A) // my code
}
},
"Build B" : {
node('Build_Server_Stack') {
buildAndArchive(B)
}
},
"Build C" : {
node('Build_Server_Stack') {
buildAndArchive(C)
}
}
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我要求在C完成后开始执行B。我可以将 B 作业从并行块中取出并添加到并行块之后来实现此目的。但在这种情况下,B 在 A 和 C 完成之前不会启动。对于长时间的 A 作业,当您有空闲的构建服务器可用时,这会影响性能。我们能否解决/改进执行计划以并行运行,但并行步骤具有“依赖性”或“优先级”。促销插件中也存在类似的机制,但需要在管道中实现。
让 B 在 C 之后执行:
parallel (
"Build A": {
node('Build_Server_Stack') {
buildAndArchive(A) // my code
}
},
"Build C then B" : {
node('Build_Server_Stack') {
buildAndArchive(C)
buildAndArchive(B)
}
}
)
Run Code Online (Sandbox Code Playgroud)
...这不是很有趣。
一个更有趣的情况是,当你有 4 个工作 A、B、C 和 D 时,C 仅依赖于 A,而 D 依赖于 A 和 B,如下所示:
A B
| \ |
C D
Run Code Online (Sandbox Code Playgroud)
有趣的是,您无法直接在 Jenkins 管道中表达这一点。无论您如何将作业安排在不同的并行块中,您总是会强制一项作业不必要地等待另一项作业。您可以合理安排您的工作:
[A, B]
[C, D]
Run Code Online (Sandbox Code Playgroud)
但即使 A 很快完成,C 也需要等待 B。
或者:
[A]
[C, B+D]
Run Code Online (Sandbox Code Playgroud)
但现在D必须等待A和B串联。
想必大多数人都会有足够的信息来选择“足够好”的配置,但不幸的是 Jenkins 似乎没有为此提供通用的解决方案。这并不是什么新想法。
为了解决这个问题,我同时运行所有并行线程,然后让每个线程依次等待它们的依赖项。像CountDownLatch这样的东西将是实现等待的完美解决方案,但这在 Jenkins 中效果不佳。Jenkins步骤waitUntil似乎很理想,但由于它基于轮询,所以在工作完成和waitUntil注意到之间不可避免地存在延迟。lock另一方面,其行为类似于互斥体。通过将两者结合起来,我们可以获得一项作业在其依赖项完成后几乎立即启动所需的行为。
// Map job name to the names of jobs it depends on.
jobDependencies = [
"A": [],
"B": [],
"C": ["A"],
"D": ["A", "B"]
]
lockTaken = [:]
threads = [:]
jobDependencies.each { name, dependencies ->
threads[name] = {
// Use a lock with a name unique to this build.
lock("${name}-${BUILD_TAG}") {
// Notify other threads that the lock has been taken and it's safe to wait on it.
lockTaken[name] = true
dependencies.each { dependency ->
// Poll until the dependency takes its lock.
waitUntil {
lockTaken[dependency]
}
// Wait for the dependency to finish and release its lock.
lock("${dependency}-${BUILD_TAG}") {}
}
// Actually run the job
buildAndArchive(name)
}
}
}
parallel threads
Run Code Online (Sandbox Code Playgroud)
这工作得很好,尽管感觉必须有更好的解决方案......我希望通过提供这个答案有人会注意到并且a)告诉我我错了并指出正确的答案;或 b) 创建一个插件来正确执行此操作;)
你绝对可以。尝试这样的事情:
stages {
stage ('Parallel build LEVEL 1 - A/C+B ...') {
parallel {
stage("Build A") {
agent { node { label 'A'}}
steps {
buildAndArchive(A)
}
}
stage("Build C and B") {
stages {
stage("Build C") {
agent { node { label 'C'}}
steps {
buildAndArchive(C)
}
}
stage("Build B") {
agent { node { label 'B'}}
steps {
buildAndArchive(B)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将并行执行两个分支,其中一个正在构建 A,另一个依次构建 C,然后构建 B。
另请参阅https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequential-stages/
| 归档时间: |
|
| 查看次数: |
5246 次 |
| 最近记录: |