在jenkins中运行两个并行的管道时发生死锁

时间:2018-05-24 09:48:19

标签: jenkins jenkins-pipeline

目前我有以下问题。 我在管道中编写了一个Jenkins文件来构建我的存储库。 每个存储库在Multibranch管道中都有自己的管道。每当我推送存储库时,管道开始工作。

对于建筑物,我有一个具有两个节点的代理。 当Multibranch Pipeline正在运行时,Multibranch Pipeline使用一个节点执行单个Pipeline,第二个节点由当前正在执行的管道用于运行单个Job。

当两个管道同时运行时,两个管道都使用一个节点。但现在问题是,由于所有节点都被占用,因此管道无法启动任何作业。这时我有一个死锁,因为两个管道都在等待一个空闲节点来完成他们的工作。

我尝试设置“disableConcurrentBuilds()”,但这只会阻止具有相同名称的Pipeline。 Multibranch Pipeline中具有不同名称的管道可以同时运行。

第二次尝试是在Jenkins文件中使用此代码设置Build Blocker Plugin。

properties([
    [$class: 'BuildBlockerProperty',
     blockLevel: 'GLOBAL',
     blockingJobs: '*pipeline_Test*',
     scanQueueFor: 'ALL',
     useBuildBlocker: true],
   disableConcurrentBuilds()
   ])

但后来我收到此错误消息。

  

WorkflowScript:30:无效的选项类型“属性”。有效选项   types:[buildDiscarder,catchError,checkoutToSubdirectory,   disableConcurrentBuilds,disableResume,durabilityHint,lock,   newContainerPerStage,overrideIndexTriggers,retry,script,   skipDefaultCheckout,skipStagesAfterUnstable,timeout,waitUntil,   withContext,withCredentials,withEnv,ws] @ line 30,column 4

如何在Jenkinsfile中为整个管道设置BuildBlockerProperty? 有没有其他方法可以阻止管道运行这么长的所有其他管道?

感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

最简单的解决方法是将执行程序的数量减少一个,确保您的执行程序总是比父作业多一个。

这样总会有一个执行程序空闲或一个子作业运行,这将完成并释放执行程序。

您可以在Manage Jenkins > Nodes > (node name) > Configure > # of executors

中设置执行者

这不是一个完整的解决方案,因为每次添加作业时都需要这样做。

答案 1 :(得分:0)

使用Lock锁定舞台或步骤。这将阻止Multibranch管道中每个分支的并行构建。

stage("Do stuff") {
  lock("my_lock") {

    // do stuff

  } // resource is unlocked.
}

答案 2 :(得分:0)

遇到同样的问题。

您没有提供Jenkinsfile,但是如果您的管道需要1个执行者节点来运行管道,另外1个节点来执行作业,则可能是在管道级别以及阶段级别都设置了一个代理,例如

pipeline {
  agent any

  stage('Build') {
    agent {
      label 'my label'
    }

    steps {
      ...
    }
  }

  post {
    always {
      ...
    }
  }
}

像我一样。当然,您的特定座席设置可能会非常不同,但是座席设置为2级。除了该阶段之外,我还必须指定一个管道级代理的原因是,否则我的post步骤将无法运行。

如果您的管道需要在阶段级别进行特定的代理设置(标签,docker映像等),则最佳做法是在管道级别设置agent none

pipeline {
  agent none

  stage('Build') {
    agent {
      label 'my label'
    }

    steps {
      ...
    }
  }
}

这样,仅需要1个执行程序节点,从而避免了死锁。

如果像我一样,您需要执行post步骤,就可以像这样

pipeline {
  agent none

  stage('Build') {
    agent {
      label 'my other label'
    }

    steps {
      ...
    }
  }

  post {
    always {
      node('label') {
        ...
      }
    }
  }
}

为其提供一个节点。标签是强制性的,尚未找到在任何节点上运行它的方法。添加node{}块使post块可以在管道级别设置agent none的情况下运行。

这对我有用,可能是OP的解决方案。 OP中提供的信息不足,无法了解管道的具体配置。

答案 3 :(得分:0)

这是我的解决方案,最后实现了它。

下图显示了我的Windows节点。管道必须在bildserver3上运行,而作业必须在buildserver2上运行。 Buldserver1是主服务器。

enter image description here

这是jenkinsfile 管道{

options {
    /*--- prevents the same branch from being built again at the same time ---*/
    disableConcurrentBuilds()
}

agent {
    node {
        /*--- define the pipeline to run on the buildserver3 ---*/
        label 'buildserver3'
    }
}


stages {
    stage('Set Build Name') {
        steps {
            script {
                 ...
            }
        }
    }
    stage('Checkout/Compile') {
        steps {
            node('buildserver2'){
                script {
                    ...
                }
            }
        }
    }
    stage('JUnit and Package') {
        steps {
            parallel(
                JUnit: {
                    node('buildserver2'){
                        script {
                            ...
                        }
                    }
                },
                Package: {
                    node('buildserver2'){
                        script {
                             ...
                        }
                    }
                }
            ) 
        }
    }
    stage('Install') {
        steps {
            node('buildserver2'){
                script {
                      ...
                }
            }
        }
    }
} 
post {
    success {
        node('buildserver2'){
          ...
        }
    }
    unstable{
        node('buildserver2'){
           ...
        }
    }
    changed {
        ....
    }
    always{
        ...
    }
}

}

重要的是,构建服务器2的节点数与jenkinsfile中配置的并行作业数相同。另外,并行作业的数量必须乘以buildserver3上的节点数量。

在这种情况下,最多并行运行两个作业,并且构建服务器3具有3个帐户,因此构建服务器2必须具有6个帐户。

如果创建的存储库具有更多并行作业,则必须相应地调整节点数。

对于同一系统上的第二个从属服务器,需要第二个Jenkins服务。以下链接下介绍了如何配置它。

https://kimbouwman.wordpress.com/2014/07/14/multiple-slaves-on-same-machine-jenkins/