CPU/メモリ使用量が高すぎると、Bashスクリプトは自動的にプロセスを終了します。

CPU/メモリ使用量が高すぎると、Bashスクリプトは自動的にプロセスを終了します。

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

答え1

はい推測する解決しようとしている問題は、時々問題が発生し、コアに永久に固定されているいくつかのプロセスがボックスで実行されていることです。

最初にすべきことは、問題を引き起こすプログラムを修復することです。これが最高のソリューションです。私はこれが不可能になるか、問題が解決されるまでボックスを実行し続けるためのクイックツールが必要だと仮定します。

少なくとも興味のある1つのプログラムだけを実行するようにスクリプトを制限したいと思います。権限がこのようにスクリプトを制限するのが最善です(たとえば、スクリプトがユーザーXで実行され、Xで実行される唯一のものはプログラムです)。

ulimit -tより良い方法は、プログラムが使用できる合計CPU時間を制限するなどのものを使用することです。繰り返しますが、すべてのメモリを消費する場合は、カーネルがこれらの制限を適用していることを確認してください。ulimit -v詳しくは、bashマンページ(シェル内蔵)とsetrlimit(2)マンページをご覧ください。

問題がランアウェイプロセスではありませんが、あまりにも多くのプロセスが実行されている場合は、X以上のプロセスが実行されないように任意の種類のロックを実装してください(または - 慣れているようですulimit -u)。また、これらのプロセスのスケジューラ優先順位を変更(niceまたは使用)するポリシーをに変更することをreniceより基本的に検討することもできます。sched_setschedulerSCHED_IDLE

さらに制御が必要な場合は、制御グループ(cgroups)を確認してください。実行中のカーネルに応じて、プロセス全体が消費するCPU時間、メモリ、I / Oなどの量を実際に制限できます。コントロールグループは非常に柔軟性があり、壊れやすい欠陥なしに必要なすべてのタスクを実行できます。 Arch Linux Wikiにはcgroupについて読む価値がある理由はNeil BrownのcgroupsシリーズLWNから。

答え2

質問:

  • 数値フィールドを並べ替えるときは、次のオプションを使用できます-nsort -nrk 2それ以外の場合、5.0の値の行は%CPU12.0の値よりも高くなります。
  • 実装に応じて、このオプションを使用してを削除psできます。これにより、インクルードの削除を防ぐことができます。--no-headersgrep -vPID
  • 私の考えでは、echo CPU USAGE is at $CPU_LOADそれはあなたの意味だと思いますecho CPU USAGE is at $CPU_USAGE
  • exit 0デバッグ(?)中に挿入したものを削除するのを忘れたようです。

スタイル:

  • CPU_USAGE_THRESHOLD=800この行は最も有益な内容であり、スクリプトが安定した後でも変更される可能性があるため、ファイルの先頭に移動することをお勧めします。
  • オプションを繰り返しています-e:same as(as is)ps -eo pid -eo pcpu -eo commandps -eo pid -o pcpu -o commandps -eo pid,pcpu,command
  • 空の条項がありますelse。これは常に処理する必要があるように見えますが、未知の理由で処理されるわけではありません。

答え3

スクリプトを作成しましたが、プロセス終了、CPU使用率がYY秒以内にXX%を超えると、配列にリストされている一部のプロセスが終了するか、ZZ秒以上実行されたプロセスが終了します。

  • ファイルの上部にXX、YY、ZZを設定できます。
  • psまたはtopを使用してプロセスを確認できます。
  • 確認できますが終了できないテスト実行モードもあります。
  • 最後に、一部のプロセスが終了すると、スクリプトは電子メールを送信します。

メモ:Githubの私のリポジトリは次のとおりです。https://github.com/padosoft/kill-process

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

         番号1

引用する

スクリプトの基本部分(topコマンドのコードの要約):

#!/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]

答え4

ほとんどのCPU /メモリを使用してプロセスを終了すると、問題が発生します。今、あなたのコンピュータに何があるかを見てください(ここでは現在、firefox、systemd(ini​​t)、Xorg、gnome-terminal、カーネルスレッドセット、xemacs;のいずれか)、それらは不可欠です。)たとえば、LinuxのOOM-killerを調整する方法を参照してください。ここ

また、「プロセスで使用されるメモリ」は、共有ライブラリ、実行可能ファイル、さらには部分データ領域までもあるため、あいまいな概念です。各ユーザーに使用されているスペースの小さな割合を請求することでいくつかの数値を計算できますが、それを追加しても実際に「使用済みメモリ」(または「プロセスが終了すると解放された」メモリ)、つまり共有部分は少なくなりません.まだ存在します) 背面).

関連情報