it-swarm.com.de

Wie kann ich einen unaufhaltsamen Zombie-Job unter Jenkins stoppen, ohne den Server neu zu starten?

Unser Jenkins-Server hat einen Job, der seit drei Tagen ausgeführt wird, aber nichts tut. Durch Klicken auf das kleine X in der Ecke wird nichts ausgeführt, und das Konsolenausgabeprotokoll zeigt auch nichts an. Ich habe unsere Build-Server überprüft und der Job scheint überhaupt nicht zu laufen.

Gibt es eine Möglichkeit, jenkins mitzuteilen, dass der Job "erledigt" ist, indem eine Datei oder eine Sperre oder etwas bearbeitet wird? Da wir viele Jobs haben, möchten wir den Server nicht wirklich neu starten.

148
blokkie

Gehen Sie zu "Jenkins verwalten"> "Skriptkonsole", um ein Skript auf Ihrem Server auszuführen und den hängenden Thread zu unterbrechen.

Sie können alle Live-Threads mit Thread.getAllStackTraces() abrufen und den hängenden unterbrechen.

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

AKTUALISIEREN:

Die obige Lösung, die Threads verwendet, funktioniert möglicherweise nicht mit neueren Jenkins-Versionen. Um eingefrorene Pipelines zu unterbrechen, beziehen Sie sich stattdessen auf this solution (by alexandru-bantiuc ) und führen Sie Folgendes aus:

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

Ich hatte auch das gleiche Problem und habe es über die Jenkins-Konsole behoben.

Gehen Sie zu "Jenkins verwalten"> "Skriptkonsole" und führen Sie ein Skript aus:

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

Sie müssen nur Ihren Jobnamen und Ihre Jobnummer angeben.

220

Ich benutze das Monitoring Plugin für diese Aufgabe. Nach der Installation des Plugins

  1. Gehen Sie zu Jenkins verwalten> Überwachung des Hudson/Jenkins-Masters
  2. Erweitern Sie die Details der Threads, den kleinen blauen Link auf der rechten Seite
  3. Suchen Sie nach dem Jobnamen, der hängt

    Der Name des Threads beginnt wie folgt

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

  4. Klicken Sie auf die rote runde Schaltfläche ganz rechts in der Tabelle der Zeile, in der sich der gewünschte Job befindet

23
cheffe

Einmal stieß ich auf einen Build, der von der "Script Console" nicht gestoppt werden konnte. Schließlich löste ich das Problem mit diesen Schritten:

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

Falls Sie einen Multibranch Pipeline - Job haben (und Sie sind ein Jenkins-Administrator), verwenden Sie in der Jenkins Script Console dieses Skript:

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

Von https://issues.jenkins-ci.org/browse/JENKINS-4302

Wenn Sie sich nicht sicher sind, wie der vollständige Name (Pfad) des Jobs lautet, können Sie das folgende Snippet verwenden, um den vollständigen Namen aller Elemente aufzulisten:

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

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

20
Markus Schulte

Die erste vorgeschlagene Lösung ist ziemlich nah. Wenn Sie stop () anstelle von interrupt () verwenden, werden sogar unkontrollierte Threads gelöscht, die in einem groovigen Systemskript endlos ausgeführt werden. Dadurch wird jeder Build beendet, der für einen Job ausgeführt wird. Hier ist der Code:

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

Wenn Sie einen nicht zu stoppenden Pipeline-Job haben, versuchen Sie Folgendes:

  1. Brechen Sie den Auftrag ab, indem Sie auf das rote X neben der Fortschrittsanzeige klicken
  2. Klicken Sie im Build auf "Pause/Fortsetzen", um die Wiedergabe anzuhalten
  3. Klicken Sie erneut auf "Pause/Fortsetzen", um den Build fortzusetzen

Pause/Resume pipeline job

Jenkins erkennt, dass der Job abgebrochen werden sollte und bricht den Build ab

12
Levente Holló

Build-Timeout-Plugin kann in solchen Fällen nützlich sein. Der Job wird automatisch beendet, wenn er zu lange dauert.

7
Draco Ater

Das beste Antwort hat fast für mich funktioniert, aber ich hatte ein großes Problem: Ich hatte eine sehr große Anzahl (~ 100) von Zombie-Jobs, weil Jenkins zu einem besonders schlechten Zeitpunkt neu gestartet wurde Name und Build-Nummer von jedem Zombie-Job und dann manuell zu töten war nicht möglich. So habe ich die Zombie-Jobs automatisch gefunden und beendet:

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

Dieses Skript durchläuft alle Builds aller Jobs und verwendet getResult().equals(null), um festzustellen, ob der Job beendet wurde oder nicht. Ein Build, der sich in der Warteschlange befindet, aber noch nicht gestartet wurde, wird nicht wiederholt (da dieser Build nicht in job.builds Enthalten ist), und ein bereits abgeschlossener Build gibt etwas anderes als null für zurück build.getResult(). Ein legitim ausgeführter Job hat auch das Build-Ergebnis null. Stellen Sie daher sicher, dass Sie keine ausgeführten Jobs haben, die Sie nicht beenden möchten, bevor Sie diesen Job ausführen.

Die mehreren verschachtelten Schleifen sind hauptsächlich erforderlich, um jeden Zweig/PR für jedes Repository in einem Multibranch-Pipeline-Projekt zu ermitteln. Wenn Sie keine Multibranch-Pipelines verwenden, können Sie alle Jobs direkt mit etwas wie Jenkins.instance.getItems().each durchlaufen.

6
jayhendren

Ich denke, es ist zu spät, um zu antworten, aber meine Hilfe einige Leute.

  1. Installieren Sie das Überwachungs-Plugin. ( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring )
  2. Gehen Sie zu jenkinsUrl/monitoring/nodes
  3. Gehen Sie zum Abschnitt Themen unten
  4. Klicken Sie auf die Detailschaltfläche links neben dem Master
  5. Sortieren nach Benutzerzeit (ms)
  6. Dann schauen Sie sich den Namen des Threads an, Sie werden den Namen und die Nummer des Builds haben
  7. Töte es

Ich habe nicht genug Ruf um Bilder zu posten.

Hoffe es kann helfen

6
Simon

Ich habe mir die Quelle von Jenkins angesehen und es scheint, dass das, was ich versuche, unmöglich ist, da das Stoppen eines Jobs anscheinend über einen Thread-Interrupt erfolgt. Ich habe keine Ahnung, warum der Job hängt obwohl ..

Bearbeiten:

Mögliche Gründe für unaufhaltsame Jobs:

  • wenn Jenkins in einer Endlosschleife steckt, kann er niemals abgebrochen werden.
  • wenn Jenkins eine Netzwerk- oder Datei-E/A-Operation innerhalb von Java VM (z. B. langwierige Dateikopie oder SVN-Aktualisierung)) ausführt, kann der Vorgang nicht abgebrochen werden.
5
blokkie

In solchen Fällen verwende ich normalerweise jenkins-cli. Sie können das Glas von einer Seite herunterladen http://your-jenkins-Host:PORT/cli. Dann renne

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

Zusatzinfo:

Sie können auch eine Reihe von Builds übergeben, z. B. 350:400. Allgemeine Hilfe beim Ausführen

Java -jar jenkins-cli.jar help

Kontextbefehlshilfe für delete-builds durch

Java -jar jenkins-cli.jar delete-builds

Kürzlich bin ich auf einen Knoten/Agenten gestoßen, auf dem ein Executor tagelang mit einem Build "X" eines Pipeline-Jobs beschäftigt war, obwohl auf dieser Jobseite behauptet wurde, Build "X" existiere nicht mehr (verworfen nach 10 nachfolgenden Builds (!), Wie in der Pipeline Job konfiguriert). Verifiziert, dass auf der Festplatte: Build "X" wirklich weg war.

Die Lösung: Es war der Agent/Knoten, der fälschlicherweise meldete, dass der belegte Executor damit beschäftigt war, Build "X" auszuführen. Das Unterbrechen des Executor-Threads hat ihn sofort freigegeben.

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

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

Andere Antworten betrachtet:

  • Die Antwort von @cheffe: hat nicht funktioniert (siehe nächster Punkt und Update unten).
  • Die Antworten mit Thread.getAllStackTraces(): kein passender Thread.
  • Die Antwort von @ levente-holló und alle Antworten mit getBuildByNumber(): traf nicht zu, da der Build nicht mehr wirklich da war!
  • Die Antwort von @austinfromboston: Das kam meinen Bedürfnissen sehr nahe, hätte aber auch andere Builds, die gerade laufen, zum Nuk gemacht.

pdate:
Ich habe wieder eine ähnliche Situation erlebt, in der ein Executor tagelang von einem (noch existierenden) fertigen Pipeline-Build besetzt war. Dieses Code-Snippet war die einzige funktionierende Lösung.

2
t0r0X

Ich hatte das gleiche Problem in der letzten halben Stunde ...

Ein Zombie-Build, der in meiner Pipeline mit mehreren Zweigen ausgeführt wird, konnte nicht gelöscht werden. Selbst ein Neustart des Servers über die Benutzeroberfläche oder sogar über die Befehlszeile mit Sudo service jenkins restart Hat die Ausführung blockiert ... Der Build konnte nicht gestoppt werden ... Es wurde immer wieder angezeigt.

Verwendete Version: Jenkins ver 2.150.2

Ich war sehr verärgert, aber als ich in das Protokoll des Builds schaute, fand ich am Ende des Protokolls etwas Interessantes:

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

Die rot markierten Teile sind die "frustrierenden Teile" ... Wie Sie sehen, wollte ich den Build von der Benutzeroberfläche abbrechen, aber es hat nicht funktioniert ...

Aber es gibt einen Hyperlink mit dem Text Click here to forcibly terminate running steps ... (erster grüner) Jetzt habe ich den Link gedrückt ...) Nach der Ausführung des Links erschien eine Meldung über Still paused Mit einem anderen Link Click here to forcibily kill entire build (Zweiter Grüner) Nach dem Drücken dieses Links wurde auch der Build endgültig hart getötet ...

Dies scheint also ohne spezielle Plugins zu funktionieren (mit Ausnahme des Multibranch-Pipeline-Build-Plugins selbst).

2
hexadez

Die Antwort von Alexandru Bantiuc hat mir gut getan, um den Bau zu stoppen, aber meine Testamentsvollstrecker waren immer noch beschäftigt. Ich konnte den Status des beschäftigten Executors folgendermaßen löschen

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

Ich hatte viele Zombi-Jobs, also habe ich folgendes Skript benutzt:

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"))
}
1
Stéphane

Hatte das gleiche Problem, aber es gab keinen Stack-Thread. Wir haben den Job mithilfe dieses Snippets in der Jenkins-Konsole gelöscht. Ersetzen Sie den Jobnamen und die Build-Nummer durch Ihre.

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

Verwenden Sie die Skriptkonsole unter 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
Poulad

Hatte ich das gleiche Problem jetzt zweimal, war das einzige Problem, das behoben wurde, den Tomcat-Server neu zu starten und den Build neu zu starten.

0
Ernie

Wenn Sie die Skriptkonsole oder zusätzliche Plugins nicht verwenden möchten, probieren Sie diese einfachen Lösungen aus, wie in https://wiki.jenkins.io/plugins/servlet/mobile?contentId=36603009#content/view/36603009 beschrieben

Pipeline-Jobs können durch Senden einer HTTP-Anforderung POST an URL-Endpunkte eines Builds gestoppt werden.

  • BUILD ID URL/stop - Bricht eine Pipeline ab.
  • BUILD ID URL/term - bricht einen Build gewaltsam ab (sollte nur verwendet werden, wenn stop nicht funktioniert.
  • BUILD ID URL/kill - Harte Beendigung einer Pipeline. Dies ist die zerstörerischste Methode zum Stoppen einer Pipeline und sollte nur als letzter Ausweg verwendet werden.
0
Dibakar Aditya

Ein von mir geschriebenes Dienstprogramm namens jkillthread kann verwendet werden, um einen beliebigen Thread in einem beliebigen Java) - Prozess anzuhalten, sofern Sie sich auf dem Computer anmelden können, auf dem der Dienst unter demselben ausgeführt wird Konto.

0
Jesse Glick

SEHR EINFACHE LÖSUNG

Der Grund, warum ich dieses Problem sah, war ein falscher Link http auf der Seite anstelle von https, der den Job stoppen sollte. Alles, was Sie tun müssen, ist das Bearbeiten des onclick Attributs in der HTML-Seite

  1. Öffnen Sie ein Konsolenprotokoll des Jobs (der Pipeline), der hängen geblieben ist
  2. Klicken Sie auf eine der verfügbaren Optionen, um den Auftrag abzubrechen (x-Symbol, "Klicken Sie hier, um die Ausführung zwangsweise abzubrechen" usw.), um den Link "Klicken Sie hier, um den gesamten Build zwangsweise abzubrechen" anzuzeigen [~ # ~] nicht [~ # ~] wird im Moment anklickbar sein)
  3. Öffnen Sie die Konsole des Browsers ( verwenden Sie eine der drei folgenden Optionen für Chrome: F12; Strg + Umschalt + i; Menü-> Weitere Tools-> Entwicklertools)
  4. Suchen Sie den Link "Klicken Sie hier, um den gesamten Build gewaltsam abzubrechen" manuell oder verwenden Sie die Schaltfläche "Element auf der Seite auswählen" der Konsole
  5. Doppelklicken Sie auf das Attribut onclick, um dessen Wert zu bearbeiten
  6. s an http anhängen, um https zu erhalten
  7. Drücken Sie die Eingabetaste, um die Änderungen zu übernehmen
  8. Klicken Sie auf den Link "Klicken Sie hier, um den gesamten Build gewaltsam abzubrechen"

Verwenden Sie den Screenshot als Referenz enter image description here

0