O processo Unix / Java pára de funcionar quando é movido para o segundo plano

1

Nós temos um processo Java que foi criado usando o Appassembler. Ele corre 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 começarmos em segundo plano, não só deixará de funcionar, como não conseguiremos ressuscitá-lo sem o colocar em 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 começando de forma inadequada? Existe uma maneira de manter o trabalho funcionando, mesmo que esteja em segundo plano? Eu preciso começar isso como um processo daemon com nohup e, em seguida, fazer logout, mas não consigo mantê-lo em execução com êxito, a menos que ele continue sendo o processo em primeiro plano, o que não é viável.

    
por Craig Otis 27.01.2015 / 17:31

1 resposta

2

Parece que as tarefas em segundo plano que aguardam a entrada estão paradas na maioria dos ambientes.

Na página da Wikipedia sobre o Job Control do Unix :

A background process that attempts to read from or write to its controlling terminal is sent a SIGTTIN (for input) or SIGTTOU (for output) signal. These signals stop the process by default, but they may also be handled in other ways.

E de uma página Rutgers sobre o uso intermediário do Unix :

A job being run in the background will stop if it needs input. Input can not be given to a background job so make sure that all input necessary is available to it.

Como uma solução nós simplesmente atualizamos nosso processo Java para aceitar um argumento opcional que fará com que o thread principal durma indefinidamente, ao invés de esperar pela entrada. Temos um gancho de desligamento que manipulará os sinais SIGTERM/SIGINT apropriadamente:

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