Prozess mit hoher CPU-Auslastung nach X-Zeit beenden? [geschlossen]

21

Unter Linux habe ich ein paar Prozesse, die gelegentlich zum Absturz neigen (Spieleserver), die am Ende 100% CPU verwenden.

Ich suche nach einem Programm oder Skript, um die CPU-Auslastung einer Liste von Prozessen nach Namen zu überprüfen. Wenn sie länger als das X. Mal, beispielsweise 30 Sekunden, zu 100% ausgelastet sind, töten Sie sie. Ich habe ps-watcher ausprobiert, konnte aber nicht feststellen, wie dies erreicht werden soll.

Nur den Prozess bei 100% Auslastung zu beenden, wird nicht funktionieren, da dies während des normalen Betriebs für kurze Zeiträume der Fall sein wird.

Ich habe auch dieses Skript gefunden, das zu tun scheint, was ich will, es ist jedoch auf einen Prozess beschränkt: Link

Jede Hilfe wird sehr geschätzt!

user30153
quelle
Kannst du bitte nochmal einen Link zum Skript posten, da dieser pastebin.com/m1c814cb4 anscheinend nicht mehr gültig ist.
Würde ich richtig raten, dass Sie Minecraft-Server ausführen? ;)
PhonicUK
@ Chris S Du bist langweilig. Das ist eine sehr interessante Frage. Können Sie eine Quelle für Ihre Behauptungen bereitstellen, "weil sie Antworten von geringer Qualität, Meinungen und Spam anziehen und die Antworten schnell veraltet sind"? Und können Sie einige Beispiele nennen, wie die vorhandenen Antworten auf diese Frage dem gerecht werden? Ich halte nicht den Atem an.
db

Antworten:

19

Versuchen Sie es mit Monit .

Sie könnten eine Konfiguration wie diese verwenden, um Ihre Aufgabe zu erfüllen:

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

Details zu dieser Konfiguration finden Sie in der Dokumentation von monit .

joschi
quelle
Danke für Ihre Antwort! Gibt es eine Möglichkeit, den Prozess zu überwachen, ohne ihn mit monit starten zu müssen? Ich habe eine Menge Server auf dem Computer, die über ein Webinterface verwaltet werden. Es ist nicht ideal, sie mit Monit zu starten.
user30153
Sicher, die Zeilen start programund stop programsind nur für den Fall monit, dass ein Neustart des Prozesses erforderlich ist. Sie können es weiterhin mit Ihrem normalen Init-Skript starten. monitSie können auch überprüfen, ob das Programm bereits ausgeführt wird (z. B. anhand der PID-Datei oder des Prozessnamens).
joschi
Fantastisch, ich denke, ich habe es herausgefunden. Das einzige Problem ist, dass es von einer PID-Datei abhängt. Ich muss eine für über 200 Prozesse generieren und Regeln für jeden erstellen, den ich nehme. Danke für die Hilfe!
User30153
4

Dies war das, wonach ich gesucht habe und benutze es seit einiger Zeit (leicht verändert). In letzter Zeit habe ich einen Fehler in meiner Arbeit gemacht, aber ich muss die App (den Spieleserver) am Laufen halten.
Ich hatte den Teil zitiert, in dem die oberste PID getötet wird, da dies die falsche PID tötete.
Hier ist mein neuester Entwurf Ihres Skripts. Bislang findet es die höchste Überlastung und beendet es effektiv (sendet mir auch eine E-Mail mit den Informationen, wann immer es etwas tut).

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


Dieses kleine Skript hat sich als äußerst nützlich erwiesen. Wenn Sie nicht möchten, dass ein Vorgang beendet wird, hilft Ihnen die E-Mail allein, Sie auf dem Laufenden zu halten.

Angelo Felix
quelle
Danke für deine Antwort! Ich möchte nur darauf hinweisen, dass Ihre Einordnung nicht möglich TOPPROCESSist. Es wird nicht nach dem tatsächlichen Wert sortiert, sondern die Einträge werden alphanumerisch sortiert (z. B. haben 6% Vorrang vor 12%). Eine bessere Alternative könnte der folgende Befehl sein:top -b -n 1 | sed 1,6d | sed -n 2p
Glutanimate
1
Wenn die CPU 90% ist, was ist die CPU_LOAD? und wie berechnet man die schwelle? Dank
Ofir Attia
1
Dies wird Situationen nicht erfassen, in denen ein Prozess auf einem Multi-Core-Server maximal genutzt wird.
UpTheCreek
0

Unten finden Sie ein BASH-Beispielskript, mit dem Sie einige Tipps für Ihre eigenen Anforderungen erhalten können.

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

Bitte beachten Sie, dass der Wert Ihres $ CPU_THRESHOLD von der Anzahl der (CPU-) Kerne abhängen sollte, die Sie auf Ihrem System haben. Eine ausführliche Erklärung zu diesem Thema finden Sie unter http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages .

Sie können Ihr Skript entweder in der Datei / etc / inittab aufrufen oder für jede gewünschte Anzahl von Minuten einen Cronjob ausführen. Beachten Sie auch, dass das Beispielskript den obersten Prozess beendet, wenn $ CPU_LOAD größer als $ CPU_THRESHOLD ist.

Bintut
quelle