Вбити процес з високим використанням процесора після часу X? [зачинено]


21

Запуск Linux У мене є кілька процесів, які час від часу виходять з ладу (ігрові сервери), які в кінцевому підсумку використовують 100% процесор.

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

Просто вбити процес при 100-відсотковому використанні не вийде, оскільки це вплине на короткий час під час нормальної роботи.

Я також знайшов цей сценарій, який, здається, робить те, що я хочу, однак він обмежений одним процесом: посиланням

Будь-яка допомога дуже вдячна!


Чи можете ви опублікувати ще раз посилання на скрипт, оскільки цей пастін.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 .


Дякую за відповідь! Чи є спосіб контролювати процес, не запускаючи його з monit? У мене на машині працює багато серверів, якими керується через веб-інтерфейс, тому що запускати їх з monit не ідеально.
user30153

Звичайно, start programі stop programрядки - це лише той випадок, коли monitпотрібно перезапустити процес. Ви все ще можете запустити його зі свого звичайного сценарію init. monitтакож може перевірити, чи програма вже запущена (наприклад, за її PID-файлом чи назвою процесу).
joschi

Фантастичний, я думаю, я це зрозумів. Єдина проблема - це залежність від 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
Glutanimate

1
Якщо процесор становить 90%, що таке CPU_LOAD? і як ви обчислюєте поріг? спасибі
Ofir Attia

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-aasures .

Ви можете або зателефонувати до свого сценарію зсередини / etc / inittab, або через cronjob, на кожну кількість хвилин, яку ви бажаєте. Зауважте також, що приклад скрипту вбиває самий верхній процес, якщо $ CPU_LOAD перевищує $ CPU_THRESHOLD.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.