X時間以上実行されている特定の名前のすべてのプロセスを強制終了する方法を探しています。私はこの特定の実行可能ファイルの多くのインスタンスを生成し、時々それは悪い状態に入り、永遠に実行され、多くのCPUを消費します。
私はすでにmonitを使用していますが、pidファイルなしでプロセスを確認する方法がわかりません。ルールは次のようになります。
kill all processes named xxxx that have a running time greater than 2 minutes
これをどのようにモニターで表現しますか?
Monitでは、PIDを持たないプロセスに一致する文字列を使用できます。 「myprocessname」という名前のプロセスの例を使用すると、
check process myprocessname
matching "myprocessname"
start program = "/etc/init.d/myproccessname start"
stop program = "/usr/bin/killall myprocessname"
if cpu usage > 95% for 10 cycles then restart
おそらく、CPU負荷が10監視サイクル(それぞれ30秒)の間、特定のレベルにあるかどうかを確認し、再起動または強制終了した場合、それはオプションかもしれません。または、プロセスに関連するファイルで モニターのタイムスタンプテスト を使用できます。
その機能を備えたすぐに使用できるツールはありません。 1分よりも長く実行されるphp-cgiスクリプトを強制終了したいとします。これを行う:
pgrep php-cgi | xargs ps -o pid,time | Perl -ne 'print "$1 " if /^\s*([0-9]+) ([0-9]+:[0-9]+:[0-9]+)/ && $2 gt "00:01:00"' | xargs kill
pgrep
は名前でプロセスを選択します、ps -o pid,time
は、すべてのpidのランタイムを出力し、次に行を分析し、そこから時間を抽出し、定義された時間と比較してpidを出力します。結果はkillに渡されました。
私はこの正確な問題をps-watcherで解決し、それについて linux.com に数年前に書きました。 ps-watcherでは、プロセスを監視し、累積実行時間に基づいてプロセスを強制終了できます。プロセスの名前が「foo」であると仮定した場合の、関連するps-watcher構成は次のとおりです。
[foo]
occurs = every
trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1
action = <<EOT
echo "$command accumulated too much CPU time" | /bin/mail user\@Host
kill -TERM $pid
EOT
[foo?]
occurs = none
action = /usr/local/etc/foo restart
キーはラインです
trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1`
これは、「累積プロセス時間が1時間を超え、かつ私が親プロセスではない場合、再起動します。
だから、私は答えがmonitを使わないことを理解していますが、それはうまくいきます。 ps-watcher は軽量でセットアップが簡単なので、モニターのセットアップに加えて実行しても問題はありません。
これをexecステートメントとしてモニターに組み込むことができます。
if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi