X 时间后是否终止 CPU 使用率高的进程?

X 时间后是否终止 CPU 使用率高的进程?

运行 Linux 时,我有几个进程偶尔会崩溃(游戏服务器),最终导致 CPU 占用达到 100%。

我正在寻找一个程序或脚本来检查按名称列出的进程的 CPU 使用率,如果这些进程处于 100% 状态的时间超过 X 时间(例如 30 秒),则终止它们。我尝试了 ps-watcher,但无法确定如何实现这一点。

仅仅终止使用率为 100% 的进程是行不通的,因为它会在正常运行期间短时间内达到这个水平。

我还发现这个脚本似乎可以完成我想要的操作,但是它仅限于一个过程:关联

任何帮助是极大的赞赏!

答案1

尝试监控

您可以使用这样的配置来完成您的任务:

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 的文档

答案2

这正是我所寻找的,并且已经使用了一段时间(略有改动)。最近,我在工作中发现了一个错误,但需要保持应用程序(游戏服务器)运行。
我引用了杀死最顶层 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


这个小脚本非常有用,如果您不喜欢它终止任何进程,那么电子邮件本身就可以帮助您随时了解情况。

答案3

下面是一个示例 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,示例脚本将终止最顶层的进程。

相关内容