Убить процесс с высокой загрузкой процессора после X раз? [закрыто]

21

Под управлением Linux у меня есть несколько процессов, которые иногда имеют сбои (игровые серверы), которые в конечном итоге используют 100% процессоров.

Я ищу программу или сценарий, чтобы проверить использование процессором списка процессов по имени, и если они находятся на 100% больше X раз, скажем, 30 секунд, убить их. Я попробовал ps-watcher, но не смог определить, как этого добиться.

Простое уничтожение процесса при 100% -ом использовании не сработает, так как это будет происходить в течение коротких периодов при нормальной работе.

Я также нашел этот скрипт, который, кажется, делает то, что я хочу, однако он ограничен одним процессом: ссылка

Любая помощь с благодарностью!

user30153
источник
Не могли бы вы опубликовать еще раз ссылку на скрипт, потому что этот pastebin.com/m1c814cb4, кажется, больше не действителен.
Буду ли я прав, предполагая, что вы используете серверы Minecraft? ;)
PhonicUK
@Chris S Ты скучный. Это очень интересный вопрос. Можете ли вы предоставить источник своих претензий "потому что они привлекают низкокачественные, опрометчивые ответы и спам, а ответы быстро устаревают"? И можете ли вы привести несколько примеров того, как существующие ответы на этот вопрос соответствуют этому? Я не задерживаю дыхание.
дб

Ответы:

19

Попробуй монит .

Вы можете использовать такую ​​конфигурацию для выполнения своей задачи:

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 .

Joschi
источник
Спасибо за ответ! Есть ли способ контролировать процесс, не запуская его с помощью monit? У меня есть тонна серверов, работающих на машине, которые управляются через веб-интерфейс, и запуск их с помощью monit не идеален.
user30153
Конечно, start programи stop programлиния только для случая , когда monitпотребности , чтобы перезагрузить ваш процесс. Вы все еще можете запустить его с помощью обычного сценария инициализации. monitтакже может проверить, запущена ли уже программа (например, по ее PID-файлу или имени процесса).
Йоси
Фантастика, я думаю, я понял это. Единственная проблема - это зависимость от pid-файла, мне нужно сгенерировать один для более чем 200 процессов и создать правила для каждого, я полагаю. Спасибо за помощь!
user30153
4

Это было то, что я искал, и использовал это в течение некоторого времени (немного измененный). В последнее время я добавил ошибку в свою работу, но мне нужно, чтобы приложение (игровой сервер) работало.
Я процитировал часть, в которой убит самый верхний 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="myemail@somewhere.org"
  # 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


Этот маленький скрипт был чрезвычайно полезен, если вам не нравится, что он убивает какой-либо процесс, только электронная почта поможет вам быть в курсе.

Анджело Феликс
источник
Спасибо за Ваш ответ! Я просто хотел бы отметить, что ваша сортировка TOPPROCESSотключена. Он не будет сортировать по фактическому значению, вместо этого он упорядочит записи в алфавитном порядке (например, 6% будет иметь приоритет над 12%). top -b -n 1 | sed 1,6d | sed -n 2p
Лучшей
1
Если процессор равен 90%, что такое CPU_LOAD? а как вы рассчитываете порог? спасибо
Офир Аттиа
1
Это не приведет к ситуациям, когда один процесс на многоядерном сервере максимально загружен.
UpTheCreek,
0

Ниже приведен пример скрипта 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.

bintut
источник