O processo Unix/Java para de ser executado quando movido para segundo plano

O processo Unix/Java para de ser executado quando movido para segundo plano

Temos um processo Java que foi criado usando Appassembler. Funciona bem desde que seja iniciado e executado em primeiro plano:

[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$ bin/ourapp
Starting in APP_HOME=/home/ec2-user/app_home
Press Q to quit

Podemos então acessar e testar o aplicativo com sucesso. No entanto, se o iniciarmos em segundo plano, ele não apenas parará de funcionar, mas também não conseguiremos reanimá-lo semtrazendo-o para o primeiro plano:

[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$ bin/ourapp &
[1] 11661
Starting in APP_HOME=/home/ec2-user/app_home
Press Q to quit
                                                     ## Not accessible!
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  jobs
[1]+  Stopped                 bin/ourapp
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  bg %1
[1]+ bin/ourapp &                                    ## Still not accessible!
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  jobs
[1]+  Stopped                 bin/ourapp
[ec2-user@ip-xxx ourapp-0.0.1-SNAPSHOT]$  fg %1
bin/ourapp                                           ## Now, it's accessible.

Estou iniciando de forma inadequada? Existe uma maneira de manter o trabalho em execução, mesmo estando em segundo plano? Preciso iniciar isso como um processo daemon nohupe depois sair, mas não consigo mantê-lo funcionando com êxito, a menos que continue sendo o processo em primeiro plano, o que não é viável.

Responder1

Parece que os trabalhos em segundo plano aguardam entradaestão paradosna maioria dos ambientes.

DePágina da Wikipedia sobre controle de tarefas Unix:

Um processo em segundo plano que tenta ler ou escrever em seu terminal de controle recebe um sinal SIGTTIN (para entrada) ou SIGTTOU (para saída). Esses sinais interrompem o processo por padrão, mas também podem ser tratados de outras maneiras.

E de umPágina Rutgers sobre uso intermediário do Unix:

Um trabalho executado em segundo plano será interrompido se precisar de entrada. A entrada não pode ser fornecida a um trabalho em segundo plano, portanto, certifique-se de que todas as entradas necessárias estejam disponíveis para ele.

Como soluçãosimplesmente atualizamos nosso processo Java para aceitar um argumento opcional que fará com que o thread principal fique suspenso indefinidamente, em vez de esperar pela entrada. Temos um gancho de desligamento que irá lidar com os SIGTERM/SIGINTsinais de forma adequada:

        if (args.length >= 0 && StringUtils.equals(args[0], "daemon")) {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

informação relacionada