サーバーを再起動せずに、Jenkinsで停止できないゾンビジョブを停止する方法


177

Jenkinsサーバーには、3日間実行されているジョブがありますが、何も実行されていません。隅にある小さなXをクリックしても何も行われず、コンソール出力ログにも何も表示されません。ビルドサーバーを確認したところ、ジョブは実際にはまったく実行されていないようです。

ファイルまたはロックなどを編集して、ジョブが「完了」したことをジェンキンスに伝える方法はありますか?多くのジョブがあるので、サーバーを再起動したくありません。


1
Jenkinsの最近のバージョンでは、このソリューションは承認済みとマークされていません。(ただし'16のもの)
NicolasW 2018年

回答:


212

[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

2
で名前を照合した後、特定のスレッドの名前を出力できt.getName()=="SOME NAME"ますか?
Zahra、2015

3
これも私を助けません-スレッドはinterrupt()に反応しません。
Zitrax、2015年

2
私にとっては割り込みが十分ではなかったため、t.stop代わりに呼び出す必要がありましたThread.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、2016年

18
これはマルチブランチプロジェクトにも適していますが、重要なのは、JobNameをJenkins.instance.getItemByFullName( "<project-name> / <branch-name>")として指定することです
evasilchenko

22
この回答は私の問題を解決するのに役立ちました。パイプラインは完全なゾンビでした。上記のスクリプトは機能せず、いくつかのjenkinsの再起動後もパイプラインは実行されていました。私はいくつかの内部クラスのドキュメントを読み、delete()メソッドを見つけたため、スクリプトは次のようJenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();になりました。
SzymonSadło2017

5
finishAbstractBuildにも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

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を使用している場合(および標準の規則に従っている場合)、<BRANCH NAME>はBranchs / my_branchの
tvt173

25

このタスクには監視プラグインを使用ます。プラグインのインストール後

  1. Jenkinsの管理> Hudson / Jenkinsマスターのモニタリングに移動します
  2. 右側の小さな青いリンクであるスレッドの詳細を展開します
  3. ハングしているジョブ名を検索します

    スレッドの名前はこのように始まります

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

  4. 希望するジョブの行のテーブルの右端にある赤い丸いボタンをクリックします


3
殺されたと表示されていますが、ページを更新すると、スレッドは生きているように見えます
Raghav S 2015

面白い。これを見てみましょう。おそらくそれはビルドに依存します。おそらくANTまたはMaven拡張機能によって外部プロセスを開始した場合、これは失敗する可能性があります。
シェフ、

これは私のために働いたソリューションです。スレッドのリストに入り、ジョブの名前を検索して赤いボタンをクリックしました。jenkinsServer / monitoring#threads
GilbertoTreviño19年

24

「スクリプトコンソール」で停止できないビルドに遭遇したら、最後に私はこれらのステップで問題を解決しました:

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

それは私の場合に実際に役立ちました:コンソールを介して
強制終了

24

最初に提案されたソリューションはかなり近いです。interrupt()の代わりにstop()を使用すると、暴走スレッドが強制終了され、groovyシステムスクリプトで無限に実行されます。これにより、ジョブで実行されるすべてのビルドが強制終了されます。これがコードです:

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

4
受け入れられるべき回答であるIMO。ビルドは既に中断された状態だったので、他のすべての回答はうまくいきませんでしたが、ビルド後のステップでハングしました。このソリューションだけが実際にビルドを停止しました
Kutzi

1
containsここでの使用は不正確で危険です。ジョブの名前が「Run Tests」の場合、「Run Tests-Integration」、「Run Tests-Unit」などの名前のジョブもすべて強制終了します。これを使用する場合は、注意してください。無関係なジョブを予期せず終了させる
Brandon

13

止められないパイプラインジョブがある場合は、以下を試してください。

  1. ビルドの進行状況バーの横にある赤いXをクリックしてジョブを中止します
  2. ビルドの「一時停止/再開」をクリックして一時停止します
  3. ビルドを再開するには、もう一度[一時停止/再開]をクリックします

パイプラインジョブの一時停止/再開

Jenkinsはジョブを終了する必要があることを認識し、ビルドを停止します


8
このメニューはありません。
papaiatis 2017年

13

スクリプトコンソールまたは追加のプラグインを使用することなく、あなたは単にすることができ、ビルドを中止入力することによって/stop/termまたは/killお使いのブラウザでビルドURLの後に。

上記のリンクから逐語的に引用:

パイプラインジョブは、ビルドのURLエンドポイントにHTTP POSTリクエストを送信することで停止できます。

  • <ビルドID URL> / stop stop-パイプラインを中止します。
  • <BUILD ID URL> / term-ビルドを強制終了します(stopが機能しない場合にのみ使用してください。
  • <ビルドID URL> / kill-パイプラインを強制終了します。これはパイプラインを停止する最も破壊的な方法であり、最後の手段としてのみ使用してください。

7

ビルドタイムアウトプラグインは、このような場合に便利です。時間がかかりすぎると、ジョブが自動的に強制終了されます。


1
残念ながら、これは私たちにとって選択肢ではありません。何日も実行されることになっているジョブがいくつかあるからです(質問しないでください)
blokkie

7
ジョブごとにビルドタイムアウトを構成します。
Draco

1
いいえ、タイムアウトが95分に設定されているビルドが3時間以上スタックしています。タイムアウトプラグインは手動で[中止]をクリックするのと同じことをしているので役に立たないと思います
Jakub Bochenski

7

答えるのは遅すぎると思いますが、私の助けとなる人もいます。

  1. 監視プラグインをインストールします。( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring
  2. jenkinsUrl / monitoring / nodesに移動します
  3. 下部の「スレッド」セクションに移動します
  4. マスターの左側にある詳細ボタンをクリックします
  5. ユーザー時間(ミリ秒)で並べ替え
  6. 次に、スレッドの名前を確認すると、ビルドの名前と番号がわかります
  7. それを殺します

申し訳ありませんが、画像を投稿するのに十分な評判がありません。

それが役に立てば幸い


1
助けていない、それは殺されたと言います。しかし、再度ページをリロードすると、そのスレッドを見ることができます
Raghav S

ビルドのスレッドまたはビルドのサブスレッドを強制終了しますか?このスレッドの名前は何ですか?あなたは良い人を殺さないと思います。ビルドのスレッドを強制終了すると、ビルドが正常に終了したことがわかります。
Simon、

2
ジョブ名も持っているスレーブのエグゼキューター番号に関連付けられているスレッドを削除してみました。また、GETの処理に関連する他のスレッドがいくつか見つかりました。含まれている情報はSubversionに関するものでした。両方を殺しても助けにはなりませんでした。最後に再起動は私を助けました。もう1つの観察は、SVNに関連付けられていない他のスレッドは強制終了できるというものでした。
Raghav S

この回答は、1か月前に投稿された@cheffe回答のコピーです。
t0r0X

6

一番上の答えはほとんどうまくいきましたが、私には1つの大きな問題がありました:特にタイミングの悪い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既に終了したビルドはnullfor 以外のものを返しますbuild.getResult()。正当に実行されているジョブには、次のビルド結果もあります。nullであるため、これを実行する前に、強制終了したくない実行中のジョブがないことを確認してください。

複数のネストされたループは、主にマルチブランチパイプラインプロジェクトのすべてのリポジトリのすべてのブランチ/ PRを検出するために必要です。マルチブランチパイプラインを使用していない場合は、のようなものを使用して、すべてのジョブを直接ループできます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が無限ループに陥っている場合、中止することはできません。
  • JenkinsがJava VM内でネットワークまたはファイルI / O(長時間のファイルコピーやSVN更新など)を実行している場合は、中止できません。

これは実際には不可能ではありません。jenkinsスクリプトコンソールを使用して、ジョブを実行しているスレッドに割り込むことができます。こちらの説明をご覧ください:stackoverflow.com/a/26306081/1434041
Zahra

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

これと同じ問題がありましたが、スタックスレッドがありませんでした。Jenkins Consoleでこのスニペットを使用してジョブを削除しました。jobnameとbuil dnumberをあなたのものに置き換えます。

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

1
これは動作しません!それはされますのみ実行中のプロセスを残しビューからビルドを削除し、すべてのリソースがロックされた
ヤクブBochenski

3

最近、パイプラインジョブのビルド "X"によって1日間エグゼキューターが占有されているノード/エージェントに遭遇しましたが、そのジョブページはビルド "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は、(まだ存在する)終了したパイプラインビルドによって数日間占有されていました。このコードスニペットは、唯一の有効なソリューションでした。


これは私にトリックをもたらしました、ありがとう!ビルド番号がすでに破棄されているため、他のソリューションは機能していませんでした(lat 5ビルドを保持するだけなので、job.getBuildByNumber(...)は何も返しませんでした)。
L.ティシュラー

2

過去30分に同じ問題が発生しました...

マルチブランチパイプラインで実行されているゾンビビルドを削除できませんでした。UIによってサーバーを再起動したり、コマンドラインからサーバーを再起動したりしてもsudo service jenkins restart 、実行がブロックされました...ビルドを停止できませんでした...常に再表示されました。

使用されているバージョン:Jenkins ver 2.150.2

私は非常にイライラしましたが...ビルドのログを調べたところ、ログの最後で何かが気になりました:

ゾンビビルドのログファイル出力と再起動の表示で停止しなかった

赤いマークの付いた部分は「イライラする部分」です...ご覧のとおり、UIからビルドを中止したかったのですが、うまくいきませんでした...

しかし、テキスト付きのハイパーリンクがありますClick here to forcibly terminate running steps...(最初の緑の1つ)次にリンクを押しました...)リンクの実行後、Still paused別のリンクClick here to forcibily kill entire build(2番目の緑の1つ)に関するメッセージが表示されましたこのリンクを押した後、ビルドも最終的に困難でした殺された...

したがって、これは特別なプラグインなしで動作するようです(multibranch-pipelineビルドプラグイン自体を除く)。


「ここをクリックしてビルド全体を強制的に強制終了するには、ここをクリックしてください」というリンクを指定した場合は、それでうまくいくので賛成票を投じます。残念ながら、ログファイルが数GBであるため、Jenkinsが最新のログを表示できないため、このソリューションはそうではありません。
mjaggard

現在、これらのログにはアクセスできません。この問題が再び発生した場合は、コメントを追加します/解決策を更新します。しかし、あなたのジェンキンスマシンでログオンして、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"))
}

1

これはいつも私にとってうまくいきます:

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

funql.orgに感謝


0

同じ問題が2回発生しましたが、修正済みのソファはtomcatサーバーを再起動してビルドを再起動することだけでした。


0

同じアカウントでサービスを実行しているマシンにログインできる限り、jkillthreadと呼ばれるユーティリティを使用して、任意のJavaプロセスの任意のスレッドを停止できます。


0

非常にシンプルなソリューション

この問題が発生した理由はhttp、ページのリンクが間違っていたためにhttpsジョブが停止することではありませんでした。あなたがする必要があるのはonclick、以下に従ってHTMLページの属性を編集することです

  1. ハングしたジョブ(パイプライン)のコンソールログを開く
  2. ジョブを強制終了するために利用できるもの(xアイコン、「実行中のステップを強制的に終了するにはここをクリック」など)をクリックして、「ビルド全体を強制的に強制終了するにはここをクリック」リンクを表示します(そうではありません)現時点ではクリックでき)。
  3. ブラウザーのコンソールを開きますchromeには3つのうちのいずれかを使用します:F12; ctrl + shift + i;メニュー->その他のツール->開発者ツール
  4. 手動で、またはコンソールの[ページ内の要素を選択]ボタンを使用して、[ここをクリックしてビルド全体を強制終了する]リンクを見つけます
  5. onclick属性をダブルクリックして値を編集します
  6. 追加shttp持っていますhttps
  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.100ブルーオーシャンのバージョンでこの問題を修正した方法を次に示します

  • インストールしたプラグインはbitbucket用のみです。
  • ノードは1つだけです。

ssh私のジェンキンスボックス
cd ~/.jenkins(私がジェンキンス を保管している場所)に
cd job/<job_name>/branches/<problem_branch_name>/builds
rm -rf <build_number>

この後、オプションで番号を変更できますnextBuildNumber(これを行いました)

最後に、jenkinsを再起動しました(brew services restart jenkins)この手順は、Jenkinsの管理方法とインストール方法によって明らかに異なります。


-3

blue-ocean UIを開始します。そこからジョブを停止してみてください。


どういう意味ですか?私のJenkinsサーバーにはそのようなUIがありません
Nico Haase

ブルーオーシャンは非常に一般的なJenkinsプラグインですここで読むことができます
user3360767 2018年

これは実際にクラシックUIとは異なる方法でジョブを中止しますか?それは疑わしいようです。
StockB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.