如何在Jenkins上停止无法阻止的僵尸作业而无需重新启动服务器?


175

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

有没有办法通过编辑某些文件或锁或其他内容来告诉jenkins该工作已“完成”?由于我们有很多工作,因此我们实际上并不想重启服务器。


1
似乎在Jenkins的最新版本中,该解决方案不是标记为已接受的解决方案。(但来自'16的
那个

Answers:


211

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

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

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

更新:

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

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

48
很棒!对于任何阅读者,您都可以通过以下方法先运行上面的命令来查看线程名称:方法调用t -> println(t.getName());
Phil

2
仍然不能与上述脚本一起使用,它可以获取脚本但不能杀死它们。
Raghav S 2015年

2
匹配中的名称后,您是否可以打印特定线程的名称t.getName()=="SOME NAME"
Zahra 2015年

3
这也无济于事-线程不对interrupt()做出反应。
Zitrax

2
对我来说中断还不够,我需要打电话给t.stopThread.getAllStackTraces().keySet().each() { t -> if (t.getName()=="YOUR THREAD NAME" ) { println(“Found, stopping now… “); t.stop(); } }
星期五

258

我也遇到了同样的问题,并通过Jenkins Console进行了修复。

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

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

您只需指定JobName和JobNumber。


我在开始其他工作的管道工作中遇到了这个问题。服务器崩溃了,其他作业都消失了,但是管道作业仍然是僵尸。我首先尝试了接受的答案,但无济于事。每次看到管道作业的进度条有些移动时,我必须多次运行@Alexandru的命令。最终,管道作业已经死了,并且为了很好的措施,我也删除了它。
Amedee Van Gasse

18
这也适用于多分支项目,但关键是将JobName指定为Jenkins.instance.getItemByFullName(“ <project-name> / <branch-name>”)
evasilchenko

22
这个答案帮助我解决了我的问题。流水线完全是僵尸。上面的脚本没有用,即使重新启动了几个詹金斯,管道仍在运行。我阅读了一些内部类文档,并找到了delete()方法,因此我的脚本如下所示:Jenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();在执行了此步骤并重新启动了詹金斯之后,僵尸构建终于消失了。
SzymonSadło17年

5
finish在AbstractBuild或FreeSyleBuild或MavenModulesetBuild中都没有方法
Jakub Bochenski

3
执行此脚本时出现问题,知道吗?groovy.lang.MissingMethodException: No signature of method: hudson.model.FreeStyleBuild.finish() is applicable for argument types: (hudson.model.Result, java.io.IOException) values: [ABORTED, java.io.IOException: Aborting build] Possible solutions: find(), findAll(), find(groovy.lang.Closure) at
Tien Dung Tran

30

如果您有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"));

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

如果不确定作业的全名(路径)是什么,则可以使用以下代码段列出所有项目的全名:

  Jenkins.instance.getAllItems(AbstractItem.class).each {
    println(it.fullName)
  };

来自https://support.cloudbees.com/hc/en-us/articles/226941767-Groovy-to-list-all-jobs


注意:如果您使用的是SVN(并且遵循标准约定),则您的<BRANCH NAME>将类似于branch / my_branch
tvt173 '18

25

将监视插件用于此任务。安装插件后

  1. 转到管理詹金斯>监视哈德森/詹金斯大师
  2. 展开线程的详细信息,右侧的蓝色小链接
  3. 搜索挂起的作业名称

    线程的名称将以此开头

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

  4. 单击所需工作所在行表中最右边的红色圆形按钮


3
它说被杀死,但是当我们刷新页面时,线程似乎还活着
Raghav S 2015年

有趣。我会看看这个。可能取决于构建。如果您已启动外部进程(可能是通过ANT或Maven扩展),则可能会失败。
Cheffe

这是对我有用的解决方案。刚进入线程列表,搜索了作业的名称,然后单击红色按钮。jenkinsServer / monitoring#threads
GilbertoTreviño19年

24

一旦我遇到了无法通过“脚本控制台”停止的构建。最后,我通过以下步骤解决了问题:

ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins

这实际上对我的情况有所帮助:通过控制台将其删除时,该作业已不存在(动态管道作业,功能分支已删除)
mkko 2016年

24

提出的第一个解决方案非常接近。如果您使用stop()而不是interrupt(),它甚至会杀死可逃脱的线程,这些线程在繁琐的系统脚本中无限地运行。这将杀死任何运行的构建。这是代码:

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

4
IMO应该是公认的答案。所有其他答案都对我不起作用,因为构建已经处于中断状态,但是挂在构建后的某个步骤中。只有此解决方案确实阻止了构建
Kutzi

1
使用contains此处是不正确且危险的-如果您的工作名称为“运行测试”,它将同时杀死所有名为“运行测试-集成”,“运行测试-单元”等的工作。意外终止无关的工作
布兰登

13

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

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

暂停/恢复管道作业

詹金斯将意识到应该终止工作并停止构建


8
我没有这个菜单项。
papaiatis

12

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

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

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

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

7

在这种情况下,构建超时插件可以派上用场。如果花费太长时间,它将自动终止该作业。


1
不幸的是,这对我们来说不是一个选择,因为我们有一些工作要运行数天(不要问)
blokkie 2013年

7
您可以基于每个作业配置构建超时。
Draco Ater 2013年

1
不,我们的构建停留了3个多小时,超时设置为95分钟,我认为超时插件无法起到帮助作用,因为它的作用与手动单击“中止”相同
Jakub Bochenski

7

我想现在回答还为时已晚,但我会帮助一些人。

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

我的信誉不足,无法发布图片。

希望能有所帮助


1
没有帮助,它说被杀。但是当页面重新加载时,我仍然可以看到该线程
Raghav S 2015年

您是杀死构建的线程还是构建的子线程?该线程的名称是什么?我猜你不会杀死好人。如果您终止了构建的线程,您将看到构建成功完成。
西蒙,2015年

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

该答案是一个月前发布的@cheffe答案的副本。
t0r0X

6

顶部的答案几乎是为我工作,但我有一个重大问题:我有僵尸工作的一个非常大的数量(约100),由于一个特别差的定时詹金斯重新启动,所以手动查找作业名称,每个版本号和每一个僵尸工作然后手动杀死它们都是不可行的。这是我自动找到并杀死僵尸工作的方式:

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

该脚本遍历所有作业的所有构建,并用于getResult().equals(null)确定作业是否完成。处于队列中但尚未开始的构建不会被迭代(因为该构建不会进入job.builds),并且已经完成的构建将返回nullfor 以外的内容build.getResult()。合法运行的作业还将具有的生成结果null,因此请确保您没有不想杀死的正在运行的作业,然后再运行。

要发现Multibranch Pipeline项目中每个存储库的每个分支/ PR,必须使用多个嵌套循环。如果您不使用Multibranch Pipelines,则可以直接使用来循环浏览所有作业Jenkins.instance.getItems().each


3
我对您的脚本进行了一些改进。 runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) } runningBuilds.each { branch->branch.doKill() }
Tobi

5

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

编辑:

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

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

实际上这并非没有可能。您可以使用jenkins脚本控制台中断正在运行作业的线程。请参阅此处的说明:stackoverflow.com/a/26306081/1434041
Zahra 2015年

3

在这种情况下,我通常使用jenkins-cli。您可以从页面下载jar http://your-jenkins-host:PORT/cli。然后跑

java -jar jenkins-cli.jar delete-builds name_of_job_to_delete hanging_job_number

辅助信息:

您也可以通过一系列构建350:400。通过运行可获得常规帮助

java -jar jenkins-cli.jar help

上下文命令帮助delete-builds

java -jar jenkins-cli.jar delete-builds

3

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()
      }
    }
  }
}

3

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

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

def executor = Jenkins.instance.getNode('NODENAME').computer.executors.find {
    it.isBusy() && it.name.contains('JOBNAME')
}

println executor?.name
if (executor?.isBusy()) executor.interrupt()

考虑的其他答案:

  • @cheffe的答案:不起作用(请参阅下一点,并在下面进行更新)。
  • 答案为Thread.getAllStackTraces():没有匹配的线程。
  • @levente-holló的答案以及所有带有getBuildByNumber():的答案都不适用于该版本,因为该构建不再存在!
  • @austinfromboston的回答:接近我的需求,但它也可能会破坏目前正在运行的任何其他版本。

更新:
我再次遇到了类似的情况,一个执行器被(仍然存在的)已完成的管道构建占用了数天。此代码段是唯一可行的解​​决方案。


这对我有用,谢谢!其他解决方案无效,因为内部版本号已经被丢弃(我们只保留了lat 5的内部版本,因​​此job.getBuildByNumber(...)没有返回任何内容)。
L. Tischler,

2

发生了同样的问题,但是没有堆栈线程。我们在Jenkins Console中使用此代码段删除了作业。将您的工作名称替换为buil dnumber。

def jobname = "Main/FolderName/BuildDefinition"
def buildnum = 6
Jenkins.instance.getItemByFullName(jobname).getBuildByNumber(buildnum).delete(); 

1
这行不通!它将仅从视图中删除构建,从而使运行中的进程和所有资源都
处于

2

我在最后一个半小时遇到了同样的问题...

无法删除在我的多分支管道中运行的僵尸版本。甚至Server也通过UI重启,甚至通过命令行sudo service jenkins restart 从命令行重启,都阻止了执行...构建不可停止...它总是会重新出现。

使用的版本:Jenkins ver 2.150.2

我很生气,但是...当查看构建日志时,我发现在日志末尾有一些有趣的地方:

僵尸版本的日志文件输出并显示重新启动并没有停止它

红色标记的部分是“令人沮丧的部分” ...正如您所看到的,我一直想从UI中止构建,但是它没有用...

但是有一个带有文本的超链接Click here to forcibly terminate running steps...(第一个绿色的)现在我按了链接...)链接执行后,关于Still paused另一个链接的消息出现了Click here to forcibily kill entire build(第二个绿色的)在按了此链接之后,构建也很困难被杀...

因此,这似乎不需要任何特殊的插件(多分支管道构建插件本身除外)也可以工作。


如果您提供了链接“单击此处以强制杀死整个构建”,那么我会投票,因为这对我有用。不幸的是,此解决方案不是因为Jenkins无法显示最新日志,因为日志文件为数GB。
mjaggard '19

抱歉,目前我无法再访问这些日志。如果再次出现此故障,我将添加评论她/更新解决方案。但是,如何在jenkins机器上登录并仅使用tail或日志查看器来获取链接呢?
de-jcup

3
这对我有用,谢谢!@mjaggard:链接为:<a href="#" onclick="new Ajax.Request('[server]/jenkins/job/[pipeline_name]/[job_number]/kill'); return false">Click here to forcibly kill entire build</a>
kaveish

1

我有很多僵尸工作,所以我使用以下脚本:

for(int x = 1000; x < 1813; x = x + 1) {
    Jenkins .instance.getItemByFullName("JOBNAME/BRANCH")
    .getBuildByNumber(x)
    .finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"))
}


0

现在我两次遇到相同的问题,唯一的解决办法是重新启动tomcat服务器并重新开始构建。



0

非常简单的解决方案

我看到此问题的原因是http页面上的链接不正确,而不是https应该停止工作。您需要做的就是onclick在html页面中编辑属性,方法如下

  1. 打开挂起的作业(管道)的控制台日志
  2. 点击任何可终止作业(X图标,“点击这里强行终止正在运行的步骤”等),以获得“点击这里强行杀死整个构建”链接可见的(这是不是会是点击的那一刻)
  3. 打开浏览器的控制台(对chrome使用以下三种之一:F12; ctrl + shift + i;菜单->更多工具->开发人员工具
  4. 手动或使用控制台的“在页面中选择元素”按钮,找到“单击此处以强制杀死整个构建”链接
  5. 双击 onclick属性以编辑其值
  6. 追加shttphttps
  7. 按Enter提交更改
  8. 单击“单击此处强制杀死整个构建”链接

使用屏幕截图作为参考 在此处输入图片说明


0

https:// my-jenkins / script上使用脚本控制台

import hudson.model.Job
import org.jenkinsci.plugins.workflow.job.WorkflowRun

Collection<Job> jobs = Jenkins.instance.getItem('My-Folder').getAllJobs()
for (int i = 0; i < jobs.size(); i++) {
  def job = jobs[i]
  for (int j = 0; j < job.builds.size(); j++) {
    WorkflowRun build = job.builds[j]
    if (build.isBuilding()) {
      println("Stopping $job ${build.number}")
      build.setResult(Result.FAILURE)
    }
  }
}

0

这些解决方案都不适合我。我必须重新启动服务器所在的计算机。不可杀的工作现在不见了。


-1

您可以只复制作业,然后删除旧的作业。如果没关系,您会丢失旧的构建日志。


-2

这是我在2.100Blue Ocean 版本中解决此问题的方法

  • 我安装的唯一插件是针对bitbucket的。
  • 我只有一个节点。

ssh放入我的詹金斯盒子
cd ~/.jenkins(存放詹金斯的 地方)
cd job/<job_name>/branches/<problem_branch_name>/builds
rm -rf <build_number>

此后,您可以选择更改编号nextBuildNumber(我这样做了)。

最后,我重新启动了jenkins(brew services restart jenkins)。根据您如何管理和安装Jenkins,此步骤显然会有所不同。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.