自动终止随着时间的推移使用 95% 以上资源的进程?Ubuntu

自动终止随着时间的推移使用 95% 以上资源的进程?Ubuntu

我不知道你的电脑怎么样,但当我的电脑正常工作时,没有任何进程会随着时间的推移消耗 95% 以上的资源。我希望有一些安全措施可以杀死任何有这种行为的进程。我之所以想到这一点,是因为当我今天早上醒来时,我的笔记本电脑已经整晚都在处理一个流浪的 Chromium 子进程。

这可能可以作为 cron 作业来完成,但在我将其作为全职工作来创建这样的工作之前,我认为我应该在这里检查一下。:) 我讨厌重新发明轮子。

答案1

其他人也遇到过这个问题,虽然 Ubuntu 似乎没有内置任何预防机制,但还是有一些想法关于如何改进这一点。

有一个类似的Serverfault 问题提到监控也许能有所帮助。

答案2

我已经创建了一个脚本,终止进程,如果 CPU 使用率在 YY 秒内大于 XX%,则杀死数组中列出的某些进程,或者杀死运行时间超过 ZZ 秒的进程。

  • 您可以在文件顶部设置XX,YY,ZZ。
  • 您可以使用 ps 或 top 来检查进程。
  • 还有一种试运行模式,用于检查但不会杀死。
  • 最后,如果某些进程被终止,脚本会发送一封电子邮件。

笔记:这是我在 Github 上的仓库:https://github.com/padosoft/kill-process

脚本的基本部分(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]

答案3

前段时间,我为我的大学课程编写了一个脚本,用于控制系统资源(CPU 和/或 RAM)的使用。您可以通过在脚本启动时编辑变量来轻松更改最大禁止使用量。脚本应在后台启动,如下所示:

nohup ./auto_killer.sh &

脚本每 N 秒查找一次使用过多资源的进程。如果某个进程使用过多资源,运行该进程的用户会在控制台上收到警告消息。如果连续两次发现同一个进程,则会将其终止(并且用户会收到有关它的信息)。

以下是代码:

#!/bin/bash

Check_Repeating_Time=3; # in seconds
Max_CPU_Usage='25.0'; #%
Max_RAM_Usage='2.0'; #%
Log_Path='/var/log/auto_killer_log'; # path to file when killing logs will be writed

while [ 1 ]; do

    ps -aux | 
    awk '{
        Username = $1;
        Proc_Name = $11;
        CPU_Usage = $3;
        RAM_Usage = $4;
        PID = $2;
        TTY = $7;

        if((CPU_Usage >= '$Max_CPU_Usage' || RAM_Usage >= '$Max_RAM_Usage' ) &&  !($1 == "USER" || $1 == "root" || $1 == "daemon" || $1 == "mysql" || $1 == "avahi" || $1 == "polkitd"))
        {
            Func_Num_of_Ocur = "cat ./auto_killer_data | grep "PID" | wc -l";
            Func_Num_of_Ocur |getline Str_Num_Of_Ocur;              

            if(Str_Num_Of_Ocur == "0")
            {
                system ("echo \"\" >> /dev/" TTY);
                system ("echo \"Process "Proc_Name" used to much of resources. It will be killed in '$Check_Repeating_Time' seconds if it wont stop!\" >> /dev/" TTY );
                system ("echo \"\" >> /dev/" TTY);
                system ("echo "PID" >> ./auto_killer_data.new");
            }
            else
            {
                system ("echo \"\" >> /dev/" TTY);
                system ("echo \"Process "Proc_Name" was killed because it used to much of system resources!\" >> /dev/" TTY );
                system ("echo \"\" >> /dev/" TTY);
                system ("kill -9 " PID);
                Data = "date";
                Data |getline Str_Data;
                system ("echo \""Str_Data"  "Username"  "Proc_Name" "TTY"\" >> '$Log_Path'");
            }
        }
    }';

    if [ -e ./auto_killer_data.new ]; then
        mv ./auto_killer_data.new ./auto_killer_data
    else    
        echo '' > ./auto_killer_data
    fi

    #We wait fo a while and repeate process
    sleep $Check_Repeating_Time\s;
done;

答案4

我之前遇到过类似的问题,这里有一小段 python 代码来解决这个问题:

链接到 Github 仓库

相关内容