3

Я не знаю о вашем компьютере, но когда мой работает должным образом, ни один процесс не отнимает 95%+ со временем. Я хотел бы иметь некоторый отказоустойчивый, который убивает любые процессы, ведущие себя так. Это приходит на ум, потому что, когда я проснулся этим утром, мой ноутбук всю ночь хрустел из-за беспризорного детского процесса с хромом.

Это, вероятно, можно сделать как работу cron, но прежде чем я сделаю это работой на полную ставку, создавая что-то вроде этого, я подумал, что должен проверить здесь. :) Ненавижу изобретать велосипед.

4 ответа4

1

Другие сталкивались с этой проблемой, и, хотя кажется, что в Ubuntu нет никаких механизмов предотвращения, есть некоторые идеи о том, как улучшить это.

Есть аналогичный вопрос о Serverfault, в котором упоминается, что Monit может помочь.

0

Некоторое время назад я написал скрипт для своих университетских классов, который контролировал использование системных ресурсов (ЦП и / или ОЗУ). Вы можете легко изменить максимальное запрещенное использование, отредактировав переменные при запуске скрипта. Сценарий должен быть запущен в фоновом режиме следующим образом:

nohup ./auto_killer.sh &

Скрипт ищет процессы, которые используют слишком много ресурсов каждые N секунд. Если какой-либо процесс использует слишком много ресурсов, пользователь, который его запускает, получает предупреждение на своей консоли. Если один и тот же процесс встречается 2 раза подряд, он уничтожается (и пользователь получает информацию об этом).

Вот код:

#!/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;
0

Я создал скрипт kill-process, который убивает некоторые процессы, перечисленные в массиве, если загрузка процессора превышает XX% в течение YY секунд или убивает процессы, которые выполняются более ZZ секунд.

  • Вы можете установить XX, YY, ZZ в верхней части файла.
  • Вы можете использовать ps или top для проверки процессов.
  • Также есть режим пробного запуска, чтобы проверить, но не убить.
  • В конце сценарий отправляет электронное письмо, если некоторые процессы были убиты.

ПРИМЕЧАНИЕ. Вот мой репозиторий на Github: https://github.com/padosoft/kill-process

Основная часть скрипта (реферат кода для верхней команды):

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

Я сталкивался с подобной проблемой раньше, и вот небольшой кусочек кода на Python для ее решения:

Ссылка на репозиторий github

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .