web-dev-qa-db-ja.com

X時間後にCPU使用率が高いプロセスを強制終了しますか?

Linuxを実行していますが、ときどきクラッシュする傾向のあるいくつかのプロセス(ゲームサーバー)があり、最終的に100%cpuを使用します。

名前でプロセスのリストのCPU使用率をチェックするプログラムまたはスクリプトを探しています。プロセスがX時間以上100%である場合、たとえば30秒であれば、それらを強制終了します。私はps-watcherを試しましたが、これを達成する方法を決定することができませんでした。

100%の使用率でプロセスを強制終了するだけでは機能しません。通常の操作中に短期間だけヒットするためです。

私が望むように動作するように見えるこのスクリプトも見つけましたが、それは1つのプロセスに制限されています: link

どんな助けでも大歓迎です!

21
user30153

monit を試してください。

次のような構成を使用して、タスクを実行できます。

check process gameserver with pidfile /var/run/gameserver.pid
  start program = "/etc/init.d/gameserver start" with timeout 60 seconds
  stop program  = "/etc/init.d/gameserver stop"
  if cpu > 80% for 2 cycles then alert
  if cpu > 95% for 5 cycles then restart
  if totalmem > 200.0 MB for 5 cycles then restart
  if loadavg(5min) greater than 10 for 8 cycles then stop
  if failed port 12345 type tcp with timeout 15 seconds
    then restart
  if 3 restarts within 5 cycles then timeout

この構成の詳細は、monitの documentation にあります。

19
joschi

これは私が探していたものであり、しばらくの間それを使用しています(少し変更されています)。最近、仕事にバグを入れましたが、アプリ(ゲームサーバー)を実行し続ける必要があります。
間違ったPIDを殺していたので、一番上のPIDが殺された部分を引用しました。
スクリプトの最新のドラフトは次のとおりです。これまでのところ、それは最上位の過負荷を検出し、事実上それを強制終了します(また、何かを実行するたびに情報をメールで送信します)。

#!/bin/bash

## Note: will kill the top-most process if the $CPU_LOAD is greater than the $CPU_THRESHOLD.
echo
echo checking for run-away process ...

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

if [ $CPU_LOAD -gt $CPU_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 load average is at $CPU_LOAD
  echo 
  echo Active processes...
  ps aux r

  # send an email using mail
  SUBJECT="Runaway Process Report at Marysol"
  # Email To ?
  EMAIL="[email protected]"
  # Email text/message
  EMAILMESSAGE="/tmp/emailmessage.txt"
  echo "System overloading, possible runaway process."> $EMAILMESSAGE
  echo "Top-most process killed $TOPPROCESS" >>$EMAILMESSAGE
  echo "Load average was at $CPU_LOAD" >>$EMAILMESSAGE
  echo "Active processes..." >>$EMAILMESSAGE
  echo "$PROCESS" >>$EMAILMESSAGE
  mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE

else
 echo
 echo no run-aways. 
 echo load average is at $CPU_LOAD
 echo 
 echo Active processes...
 ps aux r
fi
exit 0


この小さなスクリプトは非常に便利です。プロセスを強制終了したくない場合は、メールだけで情報を提供できます。

4
Angelo Felix

以下は、BASHスクリプトのサンプルであり、独自のニーズに関するヒントを得るのに役立ちます。

#!/bin/bash

CPU_LOAD=$(uptime | cut -d"," -f4 | cut -d":" -f2 | cut -d" " -f2 | sed -e "s/\.//g")
CPU_THRESHOLD=700

if [ $CPU_LOAD -gt $CPU_THRESHOLD ] ; then
  kill -9 $(ps -eo pid | sort -k 1 -r | grep -v PID | head -n 1)
fi

exit 0

$ CPU_THRESHOLDの値は、システムにある(CPU)コアの数に依存することに注意してください。このトピックに関する詳細な説明は http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages にあります。

/ etc/inittab内からスクリプトを呼び出すか、希望する分数ごとにcronjobを呼び出すことができます。 $ CPU_LOADが$ CPU_THRESHOLDより大きい場合、サンプルスクリプトは最上位のプロセスを強制終了することにも注意してください。

0
bintut