Как остановить неудержимую работу зомби на Jenkins, не перезагружая сервер?

178

У нашего сервера Jenkins есть работа, которая работает три дня, но ничего не делает. Нажатие на маленький крестик в углу ничего не дает, и журнал вывода консоли тоже ничего не показывает. Я проверил наши серверы сборки, и на самом деле эта работа, похоже, вообще не выполняется.

Есть ли способ сказать Дженкинсу, что работа «выполнена», отредактировав какой-то файл или блокировку или что-то еще? Поскольку у нас много рабочих мест, мы не хотим перезагружать сервер.

blokkie
источник
1
Кажется, в последних версиях Jenkins решение не помечено как принятое. (но с 16 года)
NicolasW

Ответы:

213

Перейдите в «Управление 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
Тем не менее, он не работает с Above script, он получает сценарии, но не убивает их.
Рагхав С
2
Вы можете напечатать имя определенной нити после сопоставления имени в t.getName()=="SOME NAME"?
Захра
3
Это мне тоже не помогает - поток не реагирует на прерывание ().
Цитрак
2
для меня прерывания было недостаточно, мне нужно было t.stopвместо этого позвонить :Thread.getAllStackTraces().keySet().each() { t -> if (t.getName()=="YOUR THREAD NAME" ) { println(“Found, stopping now… “); t.stop(); } }
пятница,
258

У меня тоже была такая же проблема и я ее исправил через консоль Jenkins.

Перейдите в «Управление Jenkins»> «Консоль скрипта» и запустите скрипт:

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

Вам нужно просто указать свои JobName и JobNumber.

Александру Бантюк
источник
У меня было это с работой Трубопровода, которая начала другие работы. Сервер вышел из строя, остальные задания исчезли, но конвейерная работа все еще была зомби. Сначала я попробовал принятый ответ, но безрезультатно. Мне приходилось запускать команду @ Alexandru несколько раз, каждый раз, когда я видел, как индикатор выполнения конвейерного задания немного сдвигался. Наконец работа конвейера умерла, и для хороших мер я тоже удалил ее.
Амеди Ван Гассе
18
Это прекрасно работает и для многоотраслевых проектов, но главное - указать JobName как Jenkins.instance.getItemByFullName ("<имя-проекта> / <имя-ветви>")
evasilchenko
22
Этот ответ помог мне решить мою проблему. Трубопровод был полным зомби. Приведенный выше скрипт не сработал, и конвейер все еще работал даже после нескольких перезапусков jenkins. Я прочитал некоторую внутреннюю документацию по классу и нашел метод delete (), поэтому мой сценарий выглядел следующим образом: Jenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();после выполнения этого и еще одного перезапуска jenkins сборка зомби наконец исчезла.
Шимон Садло
5
В finishAbstractBuild нет ни метода, ни FreeSyleBuild, ни MavenModulesetBuild
Якуб Боченски
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
Тянь Дунг Чан
31

Если у вас есть Multibranch Pipeline -job (и вы являетесь администратором Jenkins), используйте в консоли сценариев 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 (и соблюдаете стандартные соглашения), ваше <ИМЯ ФИЛИАЛА
tvt173
25

Я использую плагин мониторинга для этой задачи. После установки плагина

  1. Перейти к управлению Дженкинс> Мониторинг Хадсон / Дженкинс мастер
  2. Разверните Детали Тем, небольшая синяя ссылка на правой стороне
  3. Поиск по названию работы, которая висит

    Название темы начнется так

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

  4. Нажмите красную круглую кнопку в правой части таблицы желаемой работы

Cheffe
источник
3
Он говорит как убитый, но снова, когда мы обновляем страницу, нить кажется живой
Raghav S
Интересный. Я посмотрю на это. Вероятно, это зависит от сборки. Если вы запустили внешние процессы, возможно, с помощью расширений ANT или Maven, это может не сработать.
cheffe
Это решение, которое сработало для меня. Просто попал в список веток, сделал поиск по названию работы и нажал красную кнопку. jenkinsServer / monitor # threads
Гилберто Тревиньо,
24

Однажды я столкнулся со сборкой, которую не удалось остановить с помощью «Консоли сценариев». Наконец я решил проблему с этими шагами:

ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins
Муги
источник
это действительно помогло в моем случае: задание больше не существовало во время его уничтожения через консоль (задание динамического конвейера, ветвь функции удалена)
mkko
24

Первое предлагаемое решение довольно близко. Если вы используете stop () вместо interrupt (), это даже убивает сбегающие потоки, которые бесконечно выполняются в отличном системном скрипте. Это убьет любую сборку, которая работает для работы. Вот код:

Thread.getAllStackTraces().keySet().each() {
    if (it.name.contains('YOUR JOBNAME')) {  
      println "Stopping $it.name"
      it.stop()
    }
}
funql.org
источник
4
ИМО это должен быть принятый ответ. Все остальные ответы у меня не сработали, так как сборка уже была прервана, но это зависало на каком-то шаге после сборки. Только это решение действительно остановило сборку
Kutzi
1
Использование containsздесь некорректно и опасно - если ваше задание называется «Выполнить тесты», оно также уничтожит все задания с именами «Выполнить тесты - Интеграция», «Выполнить тесты - Модуль» и т. Д. Любой, кто использует это, должен быть осторожен, чтобы не неожиданно прекратить работу, не связанную с этим
Брэндон
14

Без того , чтобы использовать консоль сценария или дополнительные плагины, вы можете просто прервать сборки , введя /stop,/term или /killпосле URL сборки в вашем браузере.

Дословная цитата из приведенной выше ссылки:

Конвейерные задания можно остановить, отправив запрос HTTP POST на конечные точки URL-адреса сборки.

  • <BUILD ID URL> / стоп - прерывает конвейер.
  • <BUILD ID URL> / термин сборки - принудительно завершает сборку (следует использовать только в том случае, если остановка не работает.
  • <BUILD ID URL> / kill - принудительно уничтожить конвейер. Это самый разрушительный способ остановить трубопровод и должен использоваться только в качестве крайней меры.
Дибакар Адитья
источник
13

Если у вас есть неудержимая работа конвейера, попробуйте следующее:

  1. Прервите работу, нажав на красный крестик рядом с индикатором выполнения сборки.
  2. Нажмите «Приостановить / возобновить» в сборке, чтобы приостановить
  3. Нажмите «Пауза / возобновить» снова, чтобы возобновить сборку

Приостановить / возобновить работу конвейера

Дженкинс поймет, что работа должна быть прекращена и остановит сборку

Левенте Холло
источник
8
У меня нет этого пункта меню.
Папайя,
7

Плагин Build-Timeout может пригодиться для таких случаев. Это убьет работу автоматически, если это займет слишком много времени.

Драко Атер
источник
1
К сожалению, это не вариант для нас, потому что у нас есть пара заданий, которые должны работать в течение нескольких дней (не спрашивайте)
blokkie
7
Вы настраиваете тайм-ауты сборки для каждой работы.
Драко Атер
1
Нет, у нас сборка зависла более чем на 3 часа с тайм-аутом, установленным на 95 минут. Я не думаю, что плагин для тайм-аута может помочь, так как он делает то же самое, что и нажатие кнопки «Abort» вручную
Jakub Bochenski
7

Я думаю, что уже слишком поздно, чтобы ответить, но моя помощь некоторым людям.

  1. Установите плагин для мониторинга. ( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring )
  2. Перейти к jenkinsUrl / мониторинг / узлы
  3. Перейти в раздел Темы внизу
  4. Нажмите на кнопку детали слева от мастера
  5. Сортировать по времени пользователя (мс)
  6. Затем посмотрите на название потока, у вас будет имя и номер сборки
  7. Убей это

У меня недостаточно репутации, чтобы публиковать изображения извините.

Надеюсь, что это может помочь

Саймон
источник
1
Не помогает, говорит убитый. но снова, когда страница перезагружается, я вижу эту тему
Raghav S
Вы убиваете нить сборки или подпроцесс сборки? Как называется эта тема? Я думаю, ты не убиваешь хорошего. Если вы убьете поток сборки, вы увидите, что сборка завершена успешно.
Симон
2
Я попытался убить поток, связанный с номером исполнителя, который также имел имя задания. Также я нашел несколько других тем, связанных с обработкой GET, и информация содержала информацию о Subversion. Убить обоих тоже не помогло. Наконец перезагрузка мне помогла. Еще одно наблюдение было: «Другие потоки без связи с SVN» были убиты.
Рагхав С
Этот ответ является копией ответа @cheffe, который был размещен месяцем ранее.
t0r0X
6

Главный ответ почти сработал для меня, но у меня была одна большая проблема: у меня было очень большое количество (~ 100) заданий по зомби из-за особенно неудачного перезапуска Jenkins, поэтому вручную находили имя задания и номер сборки каждого и каждая работа зомби, а затем их ручное убийство были невозможны. Вот как я автоматически нашел и убил работу зомби:

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), а уже завершенная сборка будет возвращать что-то другое, чем nullдля build.getResult(). Законно запущенное задание также будет иметь результат сборки null, поэтому убедитесь, что у вас нет запущенных заданий, которые вы не хотите уничтожать, прежде чем запускать это.

Многократные вложенные циклы в основном необходимы для обнаружения каждой ветви / PR для каждого репозитория в проекте Multichranch Pipeline; если вы не используете многоотраслевые конвейеры, вы можете просто перебрать все ваши задания напрямую, например Jenkins.instance.getItems().each.

jayhendren
источник
3
Я немного улучшил твой сценарий. runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) } runningBuilds.each { branch->branch.doKill() }
Тоби
5

Я посмотрел на источник Jenkins, и кажется, что то, что я пытаюсь сделать, невозможно, потому что кажется, что остановка работы выполняется через прерывание Thread. Я понятия не имею, почему работа висит, хотя ..

Редактировать:

Возможные причины неудержимой работы:

  • если Дженкинс застрял в бесконечном цикле, его никогда нельзя прервать.
  • если Jenkins выполняет сетевой или файловый ввод-вывод в рамках Java VM (например, длительное копирование файла или обновление SVN), его нельзя прервать.
blokkie
источник
Это на самом деле не невозможно. Вы можете использовать консоль сценария jenkins, чтобы прервать поток, выполняющий вашу работу. Смотрите объяснение здесь: stackoverflow.com/a/26306081/1434041
Захра
3

Я обычно использую jenkins-cli в таких случаях. Вы можете скачать банку со страницы 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

Ответ Александру Бантука помог мне остановить сборку, но мои исполнители все еще были заняты. Я смог очистить статус занятого исполнителя, используя следующие

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()
      }
    }
  }
}
austinfromboston
источник
3

Была такая же проблема, но не было потока стека. Мы удалили задание, используя этот фрагмент в консоли Jenkins. Замените имя и номер здания на свое.

def jobname = "Main/FolderName/BuildDefinition"
def buildnum = 6
Jenkins.instance.getItemByFullName(jobname).getBuildByNumber(buildnum).delete(); 
Кеннет Кинг
источник
1
Это не работает! Это только удалит сборку из представления, оставляя работающий процесс и все ресурсы заблокированными
Якуб Боченски
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: это было близко к моим потребностям, но это также могло бы уничтожить любые другие сборки, запущенные в данный момент.

Обновление:
я снова столкнулся с подобной ситуацией, когда Исполнитель был занят в течение нескольких дней (все еще существующей) законченной сборкой конвейера. Этот фрагмент кода был единственным рабочим решением.

t0r0X
источник
Это помогло мне, спасибо! Другие решения не работали, так как номер сборки уже был отброшен (мы просто сохраняем последние 5 сборок, поэтому job.getBuildByNumber (...) ничего не возвращал).
Л. Тишлер
2

У меня была та же проблема в последние полчаса ...

Не удалось удалить сборку зомби, запущенную в моем многоотраслевом конвейере. Даже перезапуск сервера с помощью пользовательского интерфейса или даже из командной строки через sudo service jenkins restart блокировал выполнение ... Сборка не была остановлена ​​... Она всегда появлялась заново.

Используемая версия: Jenkins ver 2.150.2

Я был очень раздражен, но ... при просмотре журнала сборки я нашел что-то интересное в конце журнала:

Вывод лог файла сборки зомби и показ перезапуска не остановили его

Части, помеченные красным цветом, являются «расстраивающими частями» ... Как вы можете видеть, я всегда хотел прервать сборку из пользовательского интерфейса, но она не работала ...

Но есть гиперссылка с текстом Click here to forcibly terminate running steps... (первая зеленая) Теперь я нажал на ссылку ...) После выполнения ссылки появилось сообщение о Still pausedдругой ссылке Click here to forcibily kill entire build(вторая зеленая) После нажатия на эту ссылку сборка, наконец, тоже была тяжелой убит ...

Так что, похоже, это работает без каких-либо специальных плагинов (за исключением самого сборочного модуля многоотраслевого конвейера).

де-jcup
источник
Если бы вы дали ссылку, по которой можно перейти по ссылке «Нажмите здесь, чтобы принудительно убить всю сборку», я бы проголосовал, потому что это сработало бы для меня. К сожалению, этого решения нет, потому что Jenkins не показывает последние журналы, потому что файл журнала составляет несколько ГБ.
mjaggard
Извините, в настоящее время у меня больше нет доступа к этим журналам. Если у меня снова возникнет эта ошибка, я добавлю комментарий к ней / обновление решения. Но как насчет входа в систему на вашем компьютере 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"))
}
Stéphane
источник
1

Это работает для меня каждый раз:

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

Благодаря funql.org

Авиэль Йосеф
источник
0

Если бы одна и та же проблема случилась со мной дважды, единственным исправлением было перезапустить сервер Tomcat и перезапустить сборку.

Эрни
источник
0

Утилита, которую я написал под названием jkillthread, может использоваться для остановки любого потока в любом Java-процессе, при условии, что вы можете войти на компьютер, на котором запущена служба, под той же учетной записью.

Джесси Глик
источник
0

ОЧЕНЬ ПРОСТОЕ РЕШЕНИЕ

Причиной, по которой я видел эту проблему, была неправильная httpссылка на странице вместо того https, чтобы остановить работу. Все, что вам нужно сделать, это отредактировать onclickатрибут на html странице, выполнив

  1. Откройте консольный журнал задания (конвейера), который получил зависание
  2. Нажмите на все, что доступно, чтобы убить задание (значок x, «Нажмите здесь, чтобы принудительно прекратить выполнение шагов» и т. Д.), Чтобы получить ссылку «Нажмите здесь, чтобы принудительно убить всю сборку» (она НЕ будет активна в данный момент)
  3. Откройте консоль браузера ( используйте любой из трех для chrome: F12; ctrl + shift + i; меню-> дополнительные инструменты-> инструменты разработчика )
  4. Найдите ссылку «Нажмите здесь, чтобы принудительно уничтожить всю сборку» вручную или с помощью кнопки «выбрать элемент на странице» консоли
  5. Дважды щелкните по onclickатрибуту, чтобы изменить его значение
  6. Append , sчтобы httpиметьhttps
  7. Нажмите ввод, чтобы отправить изменения
  8. Нажмите ссылку «Нажмите здесь, чтобы принудительно убить всю сборку»

Используйте скриншот для справки введите описание изображения здесь

Сергей Плешаков
источник
0

Использование консоли Script на 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)
    }
  }
}
Poulad
источник
0

Ни одно из этих решений не помогло мне. Мне пришлось перезагрузить машину, на которой был установлен сервер. Неубиваемая работа теперь ушла.

Марк Лалиберте
источник
-1

Вы можете просто скопировать работу и удалить старую. Если не имеет значения, что вы потеряли старые журналы сборки.

GUOHUI QIAN
источник
-2

Вот как я исправил эту проблему в версии 2.100с Blue 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.

Том Бейтс
источник
-3

Войдите в интерфейс с синим океаном. Попробуйте остановить работу оттуда.

user3360767
источник
Что это значит? Мой сервер Дженкинса не имеет такого пользовательского интерфейса
Нико Хааз
Blue Ocean - очень распространенный плагин Jenkins, вы можете прочитать об этом здесь .
user3360767
Это на самом деле прерывает работу не так, как классический интерфейс? Это кажется сомнительным.
StockB