Como fazer o upstart recuar, ao invés de desistir

25

Eu quero que o Upstart faça duas coisas:

  1. pare de tentar reaparecer um processo com falha tão rapidamente
  2. nunca desista de tentar reaparecer

Em um mundo ideal, o upstart tentaria reiniciar um processo morto após 1s, depois dobrar esse atraso em cada tentativa, até chegar a uma hora.

É algo assim possível?

    
por fadedbee 28.01.2013 / 10:18

6 respostas

31

O Cookbook Upstart recomenda um atraso pós-parada ( link ). Use a sub-rotina respawn sem argumentos e ela continuará tentando para sempre:

respawn
post-stop exec sleep 5

(Eu tenho isso de esta questão do Ask Ask do Ubuntu

Para adicionar a parte de atraso exponencial, tentei trabalhar com uma variável de ambiente no script de pós-parada, acho que algo como:

env SLEEP_TIME=1
post-stop script
    sleep $SLEEP_TIME
    NEW_SLEEP_TIME='expr 2 \* $SLEEP_TIME'
    if [ $NEW_SLEEP_TIME -ge 60 ]; then
        NEW_SLEEP_TIME=60
    fi
    initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
end script

** EDITAR **

Para aplicar o atraso apenas ao respawning, evitando o atraso em uma parada real, use o seguinte, que verifica se a meta atual é "stop" ou não:

env SLEEP_TIME=1
post-stop script
    goal='initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1'
    if [ $goal != "stop" ]; then
        sleep $SLEEP_TIME
        NEW_SLEEP_TIME='expr 2 \* $SLEEP_TIME'
        if [ $NEW_SLEEP_TIME -ge 60 ]; then
            NEW_SLEEP_TIME=60
        fi
        initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
    fi
end script
    
por 22.01.2014 / 19:55
5

Como já mencionado, use respawn para acionar o respawn.

No entanto, a cobertura do livro de culinária do Upstart em respawn-limit diz que você precisará especificar respawn limit unlimited para ter um comportamento de repetição contínuo.

Por padrão, ele tentará novamente enquanto o processo não reaparecer mais de 10 vezes em 5 segundos.

Por isso, sugiro:

respawn
respawn limit unlimited
post-stop <script to back-off or constant delay>
    
por 17.10.2014 / 16:21
4

Acabei colocando um start em um cronjob. Se o serviço estiver em execução, isso não terá efeito. Se não estiver em execução, inicia o serviço.

    
por 21.10.2013 / 10:11
3

Eu fiz uma melhoria na resposta do Roger. Normalmente, você quer fazer o backoff quando há um problema no software subjacente, fazendo com que ele quebre muito em um curto período de tempo, mas uma vez que o sistema tenha se recuperado, você quer redefinir o tempo de backoff. Na versão de Roger, o serviço vai dormir por 60 segundos sempre, mesmo para travamentos isolados e isolados após 7 travamentos.

#The initial delay.
env INITIAL_SLEEP_TIME=1

#The current delay.
env CURRENT_SLEEP_TIME=1

#The maximum delay
env MAX_SLEEP_TIME=60

#The unix timestamp of the last crash.
env LAST_CRASH=0

#The number of seconds without any crash 
#to consider the service healthy and reset the backoff.
env HEALTHY_TRESHOLD=180

post-stop script
  exec >> /var/log/auth0.log 2>&1
  echo "'date': stopped $UPSTART_JOB"
  goal='initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1'
  if [ $goal != "stop" ]; then
    CRASH_TIMESTAMP=$(date +%s)

    if [ $LAST_CRASH -ne 0 ]; then
      SECS_SINCE_LAST_CRASH='expr $CRASH_TIMESTAMP - $LAST_CRASH'
      if [ $SECS_SINCE_LAST_CRASH -ge $HEALTHY_TRESHOLD ]; then
        echo "resetting backoff"
        CURRENT_SLEEP_TIME=$INITIAL_SLEEP_TIME
      fi
    fi

    echo "backoff for $CURRENT_SLEEP_TIME"
    sleep $CURRENT_SLEEP_TIME

    NEW_SLEEP_TIME='expr 2 \* $CURRENT_SLEEP_TIME'
    if [ $NEW_SLEEP_TIME -ge $MAX_SLEEP_TIME ]; then
      NEW_SLEEP_TIME=$MAX_SLEEP_TIME
    fi

    initctl set-env CURRENT_SLEEP_TIME=$NEW_SLEEP_TIME
    initctl set-env LAST_CRASH=$CRASH_TIMESTAMP
  fi
end script
    
por 17.10.2016 / 21:32
1

Você deseja respawn limit <times> <period> - embora isso não forneça o comportamento exponencial que você está procurando, provavelmente seria o caso da maioria dos casos de uso. Você pode tentar usar valores muito grandes para times e period para aproximar o que você tenta alcançar. Veja a seção man 5 init em respawn limit para referência.

    
por 28.01.2013 / 10:53
0

Outros responderam a pergunta para estrofes de respawn e respawn, mas eu gostaria de adicionar minha própria solução para o script de pós-stop que controla o atraso entre reiniciar.

O maior problema com a solução proposta por Roger Dueck é que o atraso faz com que 'restart jobName' seja interrompido até que o sono seja concluído.

Minha adição verifica se há uma reinicialização em andamento antes de determinar se deve ou não dormir.

respawn
respawn limit unlimited

post-stop script
    goal='initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1'
    if [[ $goal != "stop" ]]; then
            if ! ps aux | grep [r]estart | grep $UPSTART_JOB; then
                    sleep 60
            fi
    fi
end script
    
por 21.04.2016 / 21:26