我们的Jenkins服务器有一个已经运行了三天的作业,但是没有做任何事情。单击角落里的小X没有任何作用,控制台输出日志也没有显示任何内容。我在我们的构建服务器上检查过,该作业实际上似乎根本没有在运行。
有没有办法告诉jenkins工作已经“完成”了,比如编辑一些文件或锁之类的?因为我们有很多任务,所以我们并不想重新启动服务器。
我们的Jenkins服务器有一个已经运行了三天的作业,但是没有做任何事情。单击角落里的小X没有任何作用,控制台输出日志也没有显示任何内容。我在我们的构建服务器上检查过,该作业实际上似乎根本没有在运行。
有没有办法告诉jenkins工作已经“完成”了,比如编辑一些文件或锁之类的?因为我们有很多任务,所以我们并不想重新启动服务器。
当前回答
最近我遇到了一个节点/代理,它的一个执行程序被管道作业的构建“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的答案:这接近于我的需求,但它也会破坏目前正在运行的任何其他构建。
更新: 我再次经历了类似的情况,Executor被一个(仍然存在的)已完成的管道构建占用了数天。这个代码片段是唯一可行的解决方案。
其他回答
进入"Manage Jenkins" > "Script Console"在服务器上运行一个脚本以中断挂起的线程。
您可以使用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")
);
有一次我遇到了一个无法通过“脚本控制台”停止的构建。最后我通过以下步骤解决了这个问题:
ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins
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()
}
}
}
}
上面的答案对我来说几乎是可行的,但我有一个主要问题:由于Jenkins重启的时间特别糟糕,我有非常多的僵尸作业(大约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中),并且已经完成的构建对于build. getresult()将返回非null的值。合法运行的作业的构建结果也会为null,因此在运行此作业之前,请确保没有不想终止的正在运行的作业。
在Multibranch Pipeline项目中,多个嵌套循环主要用于发现每个存储库的每个分支/PR;如果你没有使用Multibranch pipeline,你可以直接使用Jenkins.instance.getItems().each这样的东西来循环所有的作业。
如果你有一个不可阻挡的管道作业,试试下面的方法:
通过单击构建进度条旁边的红色X来终止作业 点击构建上的“Pause/resume”暂停 再次单击“暂停/恢复”以恢复构建
Jenkins将意识到该作业应该终止并停止构建