Как остановить неустойчивую работу зомби на Дженкинсе без перезапуска сервера?

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

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

Ответ 1

Перейдите в "Управление 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")
                );

Ответ 2

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

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

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

Вы просто укажете свое JobName и JobNumber.

Ответ 3

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

  • Перейти к разделу Управление Дженкинсом > Мониторинг мастера Хадсона/Дженкинса
  • Разверните подробные сведения о потоках, маленькую синюю ссылку справа.
  • Найдите имя задания, которое висит

    Название темы начнется следующим образом

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

  • Нажмите красную круглую кнопку справа справа в таблице строки, в которой задано ваше задание

Ответ 4

Как только я столкнулся с сборкой, которая не могла быть остановлена ​​консолью Script. Наконец, я решил проблему с этими шагами:

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

Ответ 5

Если у вас есть многоотраслевой конвейер -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

Ответ 6

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

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

Ответ 7

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

  • Отмените задание, щелкнув красный X рядом со строкой выполнения сборки
  • Нажмите "Пауза/возобновить" в сборке для паузы
  • Нажмите "Пауза/возобновить" еще раз, чтобы возобновить сборку

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

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

Ответ 9

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

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

У меня недостаточно репутации, чтобы печатать фотографии.

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

Ответ 10

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

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

Этот script охватывает все сборки всех заданий и использует getResult().equals(null), чтобы определить, закончилось ли задание. Сборка, которая в очереди, но еще не запущенная, не будет повторяться (так как эта сборка не будет находиться в job.builds), а завершившаяся сборка вернет нечто, отличное от null для build.getResult(). Законченная работа также будет иметь результат сборки null, поэтому убедитесь, что у вас нет заданий, которые вы не хотите убивать, прежде чем запускать это.

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

Ответ 11

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

Изменить:

Возможные причины невыполнения заданий:

  • Если Дженкинс застрял в бесконечном цикле, он никогда не может быть прерван.
  • Если Jenkins делает сетевой или файловый ввод/вывод в Java VM (например, длительная копия файла или обновление SVN), он не может быть прерван.

Ответ 12

Обычно я использую 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

Ответ 13

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

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

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

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

Logfile output of an zombie build and showing restart did not stop it

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

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

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

Ответ 14

Ответ 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()
      }
    }
  }
}

Ответ 15

Недавно я столкнулся с узлом/агентом, у которого один исполнитель занял несколько дней по сборке "Х" задания на конвейер, хотя эта страница с запросами на сборку "Х" больше не существовала (отбрасывается после 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: это приблизилось к моим потребностям, но на нем также были бы задействованы любые другие сборки, работающие на данный момент.

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

Ответ 16

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

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

Ответ 17

У меня было много zombi-jobs, поэтому я использовал следующий скрипт:

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

Ответ 18

Если вы не хотите использовать консоль сценария или дополнительные плагины, попробуйте эти простые решения, как указано в https://wiki.jenkins.io/plugins/servlet/mobile?contentId=36603009#content/view/36603009

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

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

Ответ 19

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

Ответ 20

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

Ответ 21

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

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

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

Используйте скриншот для справки enter image description here

Ответ 22

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

Ответ 23

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

Ответ 24

Вот как я исправил эту проблему в версии 2.100 с Blue Ocean

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

ssh в мою коробку Jenkins
cd ~/.jenkins (где я держу дженкинсов)
cd job/<job_name>/branches/<problem_branch_name>/builds
rm -rf <build_number>

После этого вы можете по желанию изменить число в nextBuildNumber (я сделал это)

Наконец, я перезапустил jenkins (brew services restart jenkins). Этот шаг, очевидно, будет отличаться в зависимости от того, как вы управляете и устанавливаете Jenkins.

Ответ 25

Войдите в интерфейс Blue-Ocean. Попытайтесь остановить работу оттуда.