CPU /メモリ使用率が高くなりすぎたときにプロセスを自動的に強制終了するBashスクリプト


11

CPUやメモリの使用率が80%に達した場合にプロセスを強制終了するスクリプトを作成しました。これが発生すると、強制終了されたプロセスのリストが作成されます。それを改善するために私は何ができますか?

while [ 1 ];
do 
echo
echo checking for run-away process ...

CPU_USAGE=$(uptime | cut -d"," -f4 | cut -d":" -f2 | cut -d" " -f2 | sed -e "s/\.//g")
CPU_USAGE_THRESHOLD=800
PROCESS=$(ps aux r)
TOPPROCESS=$(ps -eo pid -eo pcpu -eo command | sort -k 2 -r | grep -v PID | head -n 1)

if [ $CPU_USAGE -gt $CPU_USAGE_THRESHOLD] ; then
  kill -9 $(ps -eo pid | sort -k 1 -r | grep -v PID | head -n 1) #original
  kill -9 $(ps -eo pcpu | sort -k 1 -r | grep -v %CPU | head -n 1)
  kill -9 $TOPPROCESS
  echo system overloading!
  echo Top-most process killed $TOPPROCESS
      echo CPU USAGE is at $CPU_LOAD

else
    fi
    exit 0
    sleep 1;
    done

3
スクリプトを実行してみましたか?while [ 1 ]このスクリプトだけでどれだけのCPUが消費されるのか不思議に思います。また、kill -9絶えず実行されているスクリプトで3つの呼び出しがありますか?これは私に悪寒を与えます...
rahmu

1
とにかく素敵なアバター、@ rahmu彼はsleep 1ループに入った
デイジー

1
その月の最初の月曜日で、私のPCは(遅い)RAID6セットをチェックしています。CPUの負荷は、このRAIDセットからのディスクIOを常に待機しているため、8を超えると簡単にピークになります。何も問題はありません。システムはまだ非常に応答が速いです。スクリプトは、使用可能な400%の3.6%のみを使用する私のFirefoxを殺します。このスクリプトで幽霊を探しているのかもしれません。ところで、システムは高負荷のために損傷を受けることはなく、メモリが不足すると、カーネルはどのプロセスを強制終了するかについて、ある程度教育された推測を行います。
ジッピー2013年

次に、ベースのロードでのプロセスの強制終了は問題ないか????
Ketan Patel 2013

私の使用例では、殺害は望ましくありません。
ジッピー2013年

回答:


11

私はよ推測あなたが解決したい問題は、あなたの箱時々誤動作だけにいくつかのプロセスを実行しているということです、そして永遠にコアをペッグ座っています。

最初にしたいことは、狂ったプログラムを修正することです。それは断然最良の解決策です。私はそれが不可能であると仮定します、またはあなたがそれが修正されるまであなたの箱を動かし続けるために迅速なクルージが必要です。

少なくとも、問題のある1つのプログラムのみにヒットするようにスクリプトを制限したいとします。権限によってスクリプトがこのように制限されている場合が最適です(たとえば、スクリプトはユーザーXとして実行され、Xとして実行される他の唯一のものはプログラムです)。

さらに良いのはulimit -t、プログラムが使用できる合計CPU時間を制限するようなものを使用することです。同様に、すべてのメモリを消費している場合は、を確認してくださいulimit -v。カーネルはこれらの制限を強制します。詳細については、bashマンページ(シェル組み込み)とsetrlimit(2)マンページを参照してください。

問題がamokを実行しているプロセスではなく、実行しているプロセスが多すぎる場合は、何らかの形式のロックを実装して、X以外のものが実行されないようにします(または、これに慣れる必要がありますulimit -u)。また、これらのプロセスのスケジューラーの優先順位を(niceまたはを使用してrenice)変更することを検討することもできます。さらに大幅sched_setschedulerに変更するには、を使用してポリシーをに変更することもできSCHED_IDLEます。

さらに制御が必要な場合は、制御グループ(cgroups)を見てください。実行しているカーネルに応じて、プロセスのグループ全体が一緒に消費するCPU時間、メモリ、I / Oなどの量を実際に制限できます。コントロールグループは非常に柔軟です。壊れやすいクルージがなくても、あなたがしようとしていることは何でもできるでしょう。Arch Linux Wikiには LWN のNeil Brownのcgroupsシリーズと同様に、読む価値のあるcgroupの紹介あります。


3

問題:

  • 数値フィールドをソートするときは、おそらく-nオプションを使用する必要がありますsort -nrk 2。それ以外の場合、%CPU値が5.0のラインは、値が12.0のラインよりも高くなります。
  • ps実装によっては、--no-headersオプションを使用してを取り除くことができますgrep -v。これにより、を含むコマンドを破棄できなくなりますPID
  • の代わりにecho CPU USAGE is at $CPU_LOAD、あなたが意味したと思いますecho CPU USAGE is at $CPU_USAGE
  • exit 0デバッグ中に挿入したものを削除するのを忘れたようです(?)。

スタイル:

  • CPU_USAGE_THRESHOLD=800これは最も情報量が多く、スクリプトが安定した後でも変更される可能性が最も高いため、ファイルの先頭に行を移動することをお勧めします。
  • -eオプションを繰り返しています:ps -eo pid -eo pcpu -eo commandps -eo pid -o pcpu -o command(そのままps -eo pid,pcpu,command)と同じです。
  • 空のelse句があります。これは常に処理する必要があるように見えますが、何らかの理由でそうではありませんでした。

2

ほとんどのCPU /メモリを使用しているプロセスを強制終了すると問題が発生します。マシンの現在の状態を確認してください(ここでは現在、firefox、systemd(ini​​t)、Xorg、gnome-terminal、カーネルスレッドのセット、xemacs、どれも必須ではありません)。例えば、LinuxのOOMキラーを微調整する方法を見てここに

また、「プロセスで使用されるメモリ」は曖昧な概念であることに注意してください。共有ライブラリ、実行可能ファイル、さらにはデータ領域の一部さえあるからです。各ユーザーに使用済みスペースのごく一部を請求することでいくつかの数字を思い付くことができますが、それを追加しても実際には「使用メモリ」は得られません(「プロセスがなくなると解放されるメモリ」は少なくなります)。後ろに)。


1

CPU使用率がYY秒間にXX%を超える場合、またはZZ秒を超えて実行されているプロセスを強制終了する場合、配列にリストされた一部のプロセスを強制終了するスクリプトkill-processを作成しました。

  • ファイルの先頭にXX、YY、ZZを設定できます。
  • チェックプロセスには、psまたはtopを使用できます。
  • チェックするだけでなく殺すための予行演習モードもあります。
  • 最後に、いくつかのプロセスが強制終了された場合、スクリプトは電子メールを送信します。

注:これがGithubの私のリポジトリです:https : //github.com/padosoft/kill-process

スクリーンショットは次のとおりです。

         ss#1

参照資料

スクリプトの重要な部分(トップコマンドのコードの要約):

#!/usr/bin/env bash

#max cpu % load
MAX_CPU=90
#max execution time for CPU percentage > MAX_CPU (in seconds 7200s=2h)
MAX_SEC=1800
#sort by cpu
SORTBY=9

#define a processes command name to check
declare -a KILLLIST
KILLLIST=("/usr/sbin/apache2" "/usr/bin/php5-cgi")

#iterate for each process to check in list
for PROCESS_TOCHECK in ${KILLLIST[*]}
do

    #retrive pid with top command order by SORTBY
    PID=$(top -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $1}')

    CPU=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $9}')
    TIME_STR=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $11}')

    # Decode the top CPU time format [dd-]hh:mm.ss.
    TIME_SEC=0
    IFS="-:" read c1 c2 c3 c4 <<< "$TIME_STR"

    #with top command time format is hh:mm.ss, so truncare seconds in c2
    c2=${c2%%.*}

    if [ -n "$c4" ]
    then
      TIME_SEC=$((10#$c4+60*(10#$c3+60*(10#$c2+24*10#$c1))))
    elif [ -n "$c3" ]
    then
      if [ "$CMD" = "ps" ]; then
        TIME_SEC=$((10#$c3+60*(10#$c2+60*10#$c1)))
      else
        TIME_SEC=$(((10#$c3*24)*60*60)+60*(10#$c2+60*10#$c1))             
      fi   
    else
      if [ "$CMD" = "ps" ]; then
        TIME_SEC=$((10#0+(10#$c2+60*10#$c1)))
      else
        TIME_SEC=$((10#0+60*(10#$c2+60*10#$c1)))
      fi
    fi

    #check if need to kill process
    if [ $CPU -gt $MAX_CPU ] && [ $TIME_SEC -gt $MAX_SEC ]; then
        kill -15 $PID
    fi

done
使用法:
bash killprocess.sh [dry|kill|--help] [top|ps] [cpu|time]

思わsortなければなりませんsort -k9nr。なしnでは、 `5.9`>を取得し29.4ます。
lk_vc 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.