如何在不重新启动服务器的情况下阻止Jenkins无法阻挡的僵尸工作?

blo*_*kie 157 jenkins

我们的Jenkins服务器有一个已经运行了三天但没有做任何事情的工作.单击角落中的小X不会执行任何操作,控制台输出日志也不会显示任何内容.我已经检查了我们的构建服务器,并且该作业实际上似乎根本没有运行.

有没有办法通过编辑某个文件或锁定或其他东西告诉詹金斯这项工作是"完成"的?由于我们有很多工作,我们真的不想重启服务器.

小智 235

我也有同样的问题,并通过Jenkins控制台修复它.

转到"管理Jenkins">"脚本控制台"并运行脚本:

 Jenkins .instance.getItemByFullName("JobName")
        .getBuildByNumber(JobNumber)
        .finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build")); 
Run Code Online (Sandbox Code Playgroud)

您只需指定JobName和JobNumber即可.

  • 这对僵尸管道工作非常有用! (24认同)
  • 这个答案帮助我解决了我的问题.管道是一个完整的僵尸.上面的脚本没有工作,即使在几个jenkins重启之后,管道仍在运行.我读了一些内部类文档,发现了一个delete()方法,所以我的脚本看起来像这样:`Jenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();`执行完之后和另一个jenkins重启僵尸的构建终于消失了. (20认同)
  • 这对于多分支项目也很有用,但关键是将JobName指定为Jenkins.instance.getItemByFullName("<project-name>/<branch-name>") (16认同)
  • AbstractBuild中没有方法`finish`,也没有FreeSyleBuild和MavenModulesetBuild (5认同)
  • 当我输入正确的职位名称和职位编号后,我遇到了另一个问题?groovy.lang.MissingMethodException:没有方法签名:hudson.maven.MavenModuleSetBuild.finish()适用于参数类型:(hudson.model.Result,java.io.IOException)值:[ABORTED,java.io.IOException:中止构建]可能的解决方案:find()、findAll()、find(groovy.lang.Closure) (3认同)
  • 谢谢!这很有效,而且非常简单.这应该是正确的答案,忘记线程. (2认同)
  • 执行此脚本时出现问题,知道吗?`groovy.lang.MissingMethodException:方法的无签名:hudson.model.FreeStyleBuild.finish()适用于参数类型:(hudson.model.Result,java.io.IOException)值:[ABORTED,java.io.IOException :正在中止构建]可能的解决方案:位于以下位置的find(),findAll(),find(groovy.lang.Closure) (2认同)
  • 作业名称:打开项目页面并注意“完整项目名称”的文本 (2认同)
  • @SzymonSadio 我注意到用delete()它已从构建历史视图中删除,但它仍然挂在执行器中,所以不幸的是,这并没有为我解决它。我还使用 finish() 方法得到以下内容:`groovy.lang.MissingMethodException:没有方法签名:hudson.model.FreeStyleBuild.finish() 适用于参数类型:(hudson.model.Result,java.io .IOException)` (2认同)

Zah*_*hra 179

转到"管理Jenkins">"脚本控制台"以在服务器上运行脚本以中断挂起的线程.

您可以获取所有活动线程Thread.getAllStackTraces()并中断挂起的线程.

Thread.getAllStackTraces().keySet().each() {
  t -> if (t.getName()=="YOUR THREAD NAME" ) {   t.interrupt();  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

使用线程的上述解决方案可能无法在更新的Jenkins版本上运行.要中断冻结管道,请参考解决方案(由alexandru-bantiuc提供)并运行:

Jenkins.instance.getItemByFullName("JobName")
                .getBuildByNumber(JobNumber)
                .finish(
                        hudson.model.Result.ABORTED,
                        new java.io.IOException("Aborting build")
                );
Run Code Online (Sandbox Code Playgroud)

  • 工作得很好!对于任何人阅读,你可以通过首先运行上面的方法来查看线程名称,方法调用`t - > println(t.getName());` (45认同)
  • 你怎么知道哪一个是停止的? (9认同)
  • 这对我没有帮助 - 线程不会对中断做出反应(). (3认同)
  • 对我来说,中断还不够,我需要调用 `t.stop` 代替: `Thread.getAllStackTraces().keySet().each() { t -&gt; if (t.getName()=="YOUR THREAD NAME" ) { println(“找到了,现在停止……”); 停止(); } }` (3认同)
  • 它仍然没有使用Above脚本,它获取脚本但不杀死相同. (2认同)
  • 你能否在匹配`t.getName()=="SOME NAME"中的名字后打印特定线程的名称? (2认同)
  • 在 Jenkins 2.235.5 上,使用更新的解决方案,我得到`groovy.lang.MissingMethodException:没有方法签名:hudson.model.FreeStyleBuild.finish() 适用于参数类型:(hudson.model.Result, java.io. IOException) 值:[ABORTED,java.io.IOException:中止构建] 可能的解决方案:find()、findAll()、find(groovy.lang.Closure)` (2认同)

Mar*_*lte 25

如果您有一个Multibranch Pipeline -job(并且您是Jenkins-admin),请在Jenkins脚本控制台中使用此脚本:

Jenkins.instance
.getItemByFullName("<JOB NAME>")
.getBranch("<BRANCH NAME>")
.getBuildByNumber(<BUILD NUMBER>)
.finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"));
Run Code Online (Sandbox Code Playgroud)

来自https://issues.jenkins-ci.org/browse/JENKINS-43020


che*_*ffe 24

我使用Monitoring Plugin执行此任务.安装插件后

  1. 转到管理Jenkins>监控Hudson/Jenkins主人
  2. 展开"线程详细信息",右侧的小蓝色链接
  3. 搜索挂起的作业名称

    Thread的名字将这样开始

    Executor #2 for master : executing <your-job-name> #<build-number>

  4. 单击所需作业所在行表格右侧的红色圆形按钮

  • 它说杀了,但是当我们刷新页面时,线程似乎还活着 (3认同)

mug*_*ugi 22

一旦我遇到了"脚本控制台"无法阻止的构建.最后我通过以下步骤解决了问题:

ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins
Run Code Online (Sandbox Code Playgroud)

  • 应该是公认的答案,我尝试了几乎所有其他答案,这个就像一个魅力。 (2认同)

小智 20

第一个提出的解决方案非常接近.如果使用stop()而不是interrupt(),它甚至会杀死失控的线程,这些线程在一个时髦的系统脚本中无休止地运行.这会杀死任何为作业运行的构建.这是代码:

Thread.getAllStackTraces().keySet().each() {
    if (it.name.contains('YOUR JOBNAME')) {  
      println "Stopping $it.name"
      it.stop()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • IMO应该是公认的答案.所有其他答案对我来说都不起作用,因为构建已经处于中断状态,但是在一些构建后的步骤中.只有这个解决方案确实停止了构建 (3认同)

Lev*_*lló 12

如果您有不可阻挡的管道作业,请尝试以下操作:

  1. 通过单击构建进度栏旁边的红色X来中止作业
  2. 单击构建上的"暂停/恢复"以暂停
  3. 再次单击"暂停/恢复"以恢复构建

暂停/恢复管道作业

Jenkins将意识到应该终止这项工作并停止构建

  • 我没有这个菜单项. (7认同)

Dra*_*ter 7

Build-timeout插件可以为这种情况派上用场.如果花费太长时间,它将自动终止作业.

  • 您可以基于每个作业配置构建超时. (7认同)

Sim*_*mon 7

我想现在回答为时已晚,但我帮助了一些人.

  1. 安装监控插件.(http://wiki.jenkins-ci.org/display/JENKINS/Monitoring)
  2. 转到jenkinsUrl/monitoring/nodes
  3. 转到底部的"线程"部分
  4. 单击主控左侧的详细信息按钮
  5. 按用户时间(ms)排序
  6. 然后查看线程的名称,您将获得构建的名称和编号
  7. 杀死它

我没有足够的声誉来发布图片抱歉.

希望它可以提供帮助

  • 我试图杀死与也有工作名称的奴隶的执行者编号相关联的线程。我还发现了与处理GET相关的其他几个线程,并且所包含的信息与Subversion有关。杀死两个人也无济于事。终于重启帮助了我。另一个观察结果是,其他没有SVN关联的线程是可杀死的。 (2认同)

jay*_*ren 6

顶部的答案几乎是为我工作,但我有一个重大问题:我有僵尸工作的一个非常大的数量(约100),由于一个特别差的定时詹金斯重新启动,所以手动查找作业名称,并建立各自的数量和每个僵尸工作,然后手动杀死他们是不可行的.这是我如何自动发现和杀死僵尸工作:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        build.doKill()
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

此脚本循环遍历所有作业的所有构建,并用于getResult().equals(null)确定作业是否已完成.在队列中但尚未启动的构建将不会被迭代(因为该构建将不在其中job.builds),并且已经完成的构建将返回除nullfor之外的其他内容build.getResult().合法运行的作业也将具有构建结果null,因此请确保在运行此作业之前没有您想要杀死的正在运行的作业.

多个嵌套循环主要用于发现Multibranch Pipeline项目中每个存储库的每个分支/ PR; 如果您没有使用Multibranch Pipelines,您可以直接使用类似的东西遍历所有作业Jenkins.instance.getItems().each.

  • 我略微改进了你的脚本.`runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll(){it.getResult().equals(null)} runningBuilds.each {branch-> branch.doKill()}` (2认同)

blo*_*kie 5

我看过Jenkins的来源,似乎我想做的事情是不可能的,因为停止工作似乎是通过线程中断来完成的.我不知道为什么工作挂了..

编辑:

不可阻挡的工作可能的原因:

  • 如果詹金斯陷入无限循环,它永远不会被中止.
  • 如果Jenkins在Java VM中进行网络或文件I/O(例如冗长的文件复制或SVN更新),则不能中止.


aus*_*ton 5

Alexandru Bantiuc 的回答对我停止构建很有效,但我的执行者仍然很忙。我可以使用以下方法清除繁忙的执行程序状态

server_name_pattern = /your-servers-[1-5]/
jenkins.model.Jenkins.instance.getComputers().each { computer ->
  if (computer.getName().find(server_name_pattern)) {
    println computer.getName()
    execList = computer.getExecutors()      
    for( exec in execList ) {
      busyState = exec.isBusy() ? ' busy' : ' idle'
      println '--' + exec.getDisplayName() + busyState
      if (exec.isBusy()) {
        exec.interrupt()
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


t0r*_*r0X 5

最近,我遇到一个节点/代理,其中一个执行程序被管道作业的构建“X”占用了数天,尽管该作业页面声称构建“X”不再存在(在 10 个后续构建后被丢弃(!),因为在管道作业中配置)。已验证磁盘上:构建“X”确实消失了。

\n\n

解决方案:代理/节点错误地报告占用的执行器正忙于运行构建“X”。中断该执行器的线程会立即释放它。

\n\n
def executor = Jenkins.instance.getNode(\'NODENAME\').computer.executors.find {\n    it.isBusy() && it.name.contains(\'JOBNAME\')\n}\n\nprintln executor?.name\nif (executor?.isBusy()) executor.interrupt()\n
Run Code Online (Sandbox Code Playgroud)\n\n

考虑的其他答案:

\n\n
    \n
  • @cheffe 的答案:不起作用(请参阅下一点,并在下面更新)。
  • \n
  • 答案是Thread.getAllStackTraces():没有匹配的线程。
  • \n
  • @levente-holl\xc3\xb3 的答案和所有带有getBuildByNumber(): 的答案都不适用,因为构建不再存在了!
  • \n
  • @austinfromboston 的答案:这很接近我的需求,但它也会破坏目前正在运行的任何其他构建。
  • \n
\n\n

更新:
\n我再次经历了类似的情况,其中执行器被(仍然存在的)已完成的管道构建占用了数天。该代码片段是唯一可行的解​​决方案。

\n


Dib*_*tya 5

而不必使用脚本控制台或额外的插件,你可以简单地中止构建的进入/stop/term/kill之后在浏览器中生成URL。

从上面的链接中逐字引用:

可以通过向构建的URL端点发送HTTP POST请求来停止管道作业。

  • BUILD ID URL / stop-中止管道。
  • BUILD ID URL / term-强制终止构建(仅当stop不起作用时才应使用。
  • BUILD ID URL / kill-强制终止管道。这是停止管道的最具破坏性的方式,应仅用作最后的手段。