Matar o processo com alto uso da CPU após o tempo X? [fechadas]

21

Executando o Linux Eu tenho alguns processos que tendem a travar ocasionalmente (servidores de jogos), que acabam usando 100% da CPU.

Estou procurando um programa ou script para verificar o uso da CPU de uma lista de processos por nome e se eles estiverem em 100% por mais de X tempo, digamos 30 segundos, mate-os. Eu tentei ps-watcher, mas não foi capaz de determinar como fazer isso.

Acabar com o processo com 100% de uso não funcionará, pois ocorrerá por breves períodos durante a operação normal.

Eu também encontrei esse script que parece fazer o que eu quero, no entanto, é limitado a um processo: link

Qualquer ajuda é muito apreciada!

user30153
fonte
Você pode postar novamente um link para o script, pois este pastebin.com/m1c814cb4 parece não ser mais válido.
Eu estaria certo ao supor que você está executando servidores Minecraft? ;)
PhonicUK
@ Chris S Você é chato. Esta é uma questão muito interessante. Você pode fornecer uma fonte para suas reivindicações "porque elas atraem respostas de baixa qualidade, opinativas e de spam, e as respostas se tornam obsoletas rapidamente"? E você pode dar alguns exemplos de como as respostas existentes para essa pergunta correspondem a isso? Eu não estou segurando minha respiração.
db

Respostas:

19

Tente monit .

Você pode usar uma configuração como esta para realizar sua tarefa:

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

Detalhes sobre esta configuração podem ser encontrados na documentação do monit .

joschi
fonte
Obrigado pela resposta! Existe alguma maneira de monitorar o processo sem precisar iniciá-lo com o monit? Eu tenho uma tonelada de servidores em execução na máquina que são gerenciados por meio de uma interface da web, não é ideal iniciá-los com o monit.
user30153
Claro, as linhas start programe stop programsão apenas para o caso em que é monitnecessário reiniciar o processo. Você ainda pode iniciá-lo com seu script init normal. monitTambém é possível verificar se o programa já está em execução (por exemplo, pelo arquivo PID ou pelo nome do processo).
Joschi
Fantástico, acho que já descobri. O único problema é a dependência de um arquivo pid, vou precisar gerar um para mais de 200 processos e criar regras para cada um que suponho. Obrigado pela ajuda!
user30153
4

Era isso que eu estava procurando e já o uso há algum tempo (um pouco alterado). Ultimamente, eu coloquei um bug no meu trabalho, mas preciso manter o aplicativo (servidor de jogos) em execução.
Eu citei a parte em que o PID mais alto é morto, pois estava matando o PID errado.
Aqui está o meu rascunho mais recente do seu script, até o momento, ele encontra a sobrecarga máxima e a mata efetivamente (também me envia um e-mail com as informações sempre que faz alguma coisa);

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


Esse pequeno script foi extremamente útil; se você não gostar de matar nenhum processo, apenas o e-mail ajudará a mantê-lo informado.

Angelo Felix
fonte
Obrigado pela sua resposta! Gostaria apenas de salientar que a sua classificação TOPPROCESSestá desativada. Ele não classificará pelo valor real; em vez disso, ordenará as entradas alfanumericamente (por exemplo, 6% terão precedência sobre 12%). Uma alternativa melhor pode ser o seguinte comando:top -b -n 1 | sed 1,6d | sed -n 2p
Glutanimate 11/13
1
Se a CPU é 90%, qual é o CPU_LOAD? e como você calcula o limite? obrigado
Ofir Attia
1
Isso não captura situações em que um processo é atingido no máximo em um servidor com vários núcleos.
UpTheCreek
0

Abaixo está um exemplo de script BASH que pode ajudá-lo a obter algumas dicas para suas próprias necessidades.

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

Observe que o valor do seu $ CPU_THRESHOLD deve depender do número de núcleos (CPU) existentes no seu sistema. Uma explicação detalhada sobre esse tópico pode ser encontrada em http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages .

Você pode chamar seu script de dentro do / etc / inittab ou um cronjob para cada número de minutos que preferir. Observe também que o script de exemplo eliminará o processo mais alto se o $ CPU_LOAD for maior que o $ CPU_THRESHOLD.

bintut
fonte