O daemon falha mas o upstart pensa que ainda está vivo

1

Eu tenho que seguinte problema: Nós temos um aplicativo Java que é iniciado por um script bash. Este aplicativo deve ser executado como um daemon, portanto, temos um trabalho inicial para iniciá-lo.

start on runlevel [2345]                    
stop on runlevel [!2345]                    

#tell upstart we will fork later, so it will mangage the pids. 
 expect fork


#If the daemon stoppes unexpectedly, restart it! 
respawn
script
  #The framework will only work, if we start it from this directory.
  cd /usr/lib/app-dir
  nohup ./appStartScript.sh &> /dev/null &

  #send an upstart event, in case we will chain this job later
  emit app_running                         
end script

Às vezes, o aplicativo pára de funcionar. Não existe nem um arquivo .hprof, nem um arquivo hserr que é normalmente criado se a VM falhar. Upstart reporte o aplicativo como em execução,

appDeamon start/running, process 1131

Mas o PID não está listado em ps -aux . (Além disso, o upstart não é capaz de parar o processo com parar appDeamon .)

Eu gostaria de saber:  a) Por que o newstart não reconhece que o aplicativo falhou?  b) Existe a possibilidade de forçar o início da reinicialização do aplicativo, mesmo que o processo com o pid informado não esteja mais presente? (Até agora, precisamos reiniciar o servidor inteiro.)

Nosso sistema é o Ubuntu Linux 10.04.1 LTS.

    
por Arvodan 25.07.2012 / 15:25

2 respostas

1

Isso é o que geralmente acontece com programas daemon:

  1. Upstart executa o executável no primeiro plano
  2. O programa carrega o arquivo de configuração, verifica, executa várias operações de configuração (como abrir uma porta de escuta).
  3. Se a etapa anterior falhar, o programa sai e o upstart obtém um código de saída diferente de zero, portanto, sabendo que ele falhou
  4. Se a etapa 2 não falhar, o programa agora se bifurca, criando essencialmente duas cópias dela
  5. O processo que o Upstart executou agora sai com um código de saída zero, indicando que foi bem-sucedido
  6. O processo bifurcado continua em execução e faz o trabalho real do aplicativo

O problema é que o Java não fornece um mecanismo para bifurcar e, portanto, esse padrão experimentado e testado não pode ser implementado corretamente. Ao executar daemons Java, você é forçado a colocar em segundo plano o processo imediatamente (ou seja, o símbolo & no script). Inicialmente, o Startstart inicia o processo e imediatamente se esquece disso - o processo não tem como indicar ao Upstart se ele foi inicializado com sucesso ou não.

A única maneira de contornar isso é iniciar o processo, contextualizá-lo e, em seguida, verificar se ele ainda está sendo executado para determinar se foi bem-sucedido ou não. A pegada, claro, é determinar quando para verificar se ainda está em execução. A solução simples é algo assim:

#!/bin/sh
java MyClass >/dev/null 2>&1 &
PID=$!
sleep 3
if kill -0 $PID; then
    exit 0
else
    exit 1
fi

Existem mais esquemas elaborados para determinar quando verificar o processo, como fechar o programa stdout e stderr ou crie seu arquivo PID quando terminar sua rotina de inicialização e aguarde esses eventos no script de inicialização.

A solução mais simples para você é modificar seu script Upstart para algo assim:

script
    cd /usr/lib/app-dir
    nohup ./appStartScript.sh &> /dev/null &
    PID=$!
    sleep 3
    if kill -0 $PID; then
        emit app_running                         
        exit 0
    else
        exit 1
    fi
end script
    
por 26.07.2012 / 08:15
0

Por que seu aplicativo precisa ser iniciado por um script bash ? O Upstart precisa saber quantas vezes o seu aplicativo é forjado. Você disse que ele não é bifurcado (já que você não especificou a sub-rotina ' expect ') e, no entanto, você bifurcou (porque especificou ' & ' na seção de script. Portanto, o Upstart não pode para rastrear o PID.

Por favor, veja:

por 26.07.2012 / 21:25

Tags