Zabić proces przy dużym zużyciu procesora po czasie X? [Zamknięte]

21

W systemie Linux mam kilka procesów, które czasami ulegają awarii (serwery gier), które kończą przy użyciu 100% procesora.

Szukam programu lub skryptu, aby sprawdzić użycie procesora przez listę procesów według nazwy i jeśli są one w 100% dłużej niż X czas, powiedzmy 30 sekund, zabij je. Próbowałem ps-watchera, ale nie byłem w stanie określić, jak to osiągnąć.

Samo zabicie procesu przy 100% użyciu nie zadziała, ponieważ uderzy to w krótkie okresy podczas normalnej pracy.

Znalazłem również ten skrypt, który wydaje się robić to, co chcę, ale jest ograniczony do jednego procesu: linku

Każda pomoc jest mile widziana!

użytkownik30153
źródło
Czy możesz ponownie opublikować link do skryptu, ponieważ ten pastebin.com/m1c814cb4 wydaje się już nieaktualny.
Czy miałbym rację zgadując, że korzystasz z serwerów Minecraft? ;)
PhonicUK
@Chris S You are nudny. To bardzo interesujące pytanie. Czy możesz podać źródło swoich roszczeń „ponieważ przyciągają one odpowiedzi niskiej jakości, z opiniami i spamem, a odpowiedzi szybko stają się przestarzałe”? Czy możesz podać kilka przykładów, w jaki sposób istniejące odpowiedzi na to pytanie odpowiadają temu? Nie wstrzymuję oddechu.
db

Odpowiedzi:

19

Spróbuj Monit .

Możesz użyć takiej konfiguracji, aby wykonać swoje zadanie:

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

Szczegóły dotyczące tej konfiguracji można znaleźć w dokumentacji monitora .

joschi
źródło
Dziękuję za odpowiedź! Czy jest jakiś sposób na monitorowanie procesu bez konieczności uruchamiania go z monitem? Mam mnóstwo serwerów uruchomionych na komputerze, które są zarządzane przez interfejs sieciowy, konieczność uruchamiania ich za pomocą monitora nie jest idealna.
user30153,
Jasne, linie start programi stop programsą tylko w przypadku, gdy monittrzeba ponownie uruchomić proces. Nadal możesz uruchomić go za pomocą zwykłego skryptu inicjującego. monitmoże również sprawdzić, czy program jest już uruchomiony (np. przez swój plik PID lub nazwę procesu).
joschi
Fantastycznie, myślę, że to rozgryzłem. Jedynym problemem jest to, że zależy od pliku pid, będę musiał wygenerować jeden dla ponad 200 procesów i stworzyć reguły dla każdego z nich. Dzięki za pomoc!
user30153,
4

Właśnie tego szukałem i używałem go od jakiegoś czasu (nieco zmieniony). Ostatnio umieściłem błąd w mojej pracy, ale muszę utrzymać działanie aplikacji (serwera gry).
Zacytowałem część, w której zabija się najwyższy PID, ponieważ zabija niewłaściwy PID.
Oto mój najnowszy szkic twojego skryptu, do tej pory znajduje on najwyższe przeciążenie i skutecznie go zabija (także e-mailem z informacją, gdy cokolwiek robi);

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


Ten mały skrypt jest niezwykle przydatny, jeśli nie podoba Ci się zabicie jakiegokolwiek procesu, sam e-mail pomoże Ci na bieżąco otrzymywać informacje.

Angelo Felix
źródło
Dzięki za odpowiedź! Chciałbym tylko zaznaczyć, że twoje sortowanie TOPPROCESSjest wyłączone. Nie sortuje według wartości rzeczywistej, zamiast tego porządkuje wpisy alfanumerycznie (np. 6% będzie miało pierwszeństwo przed 12%). Lepszą alternatywą może być następujące polecenie:top -b -n 1 | sed 1,6d | sed -n 2p
Glutanimate,
1
Jeśli procesor wynosi 90%, co to jest CPU_LOAD? i jak obliczyć próg? dzięki
Ofir Attia
1
Nie wychwytuje to sytuacji, w których jeden proces jest maksymalnie wykorzystany na serwerze wielordzeniowym.
UpTheCreek
0

Poniżej znajduje się przykładowy skrypt BASH, który może pomóc ci uzyskać wskazówki dotyczące własnych potrzeb.

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

Pamiętaj, że wartość twojego $ CPU_THRESHOLD powinna zależeć od liczby rdzeni (CPU), które masz w systemie. Szczegółowe wyjaśnienie tego tematu można znaleźć na stronie http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages .

Możesz wywołać swój skrypt z poziomu pliku / etc / inittab lub cronjob na każdą liczbę minut, którą wolisz. Należy również pamiętać, że przykładowy skrypt zabije najwyższy proces, jeśli $ CPU_LOAD jest większy niż $ CPU_THRESHOLD.

Bintut
źródło