Unix/Java 进程移至后台时停止运行

Unix/Java 进程移至后台时停止运行

我们有一个使用 Appassembler 创建的 Java 进程。只要启动并在前台运行,它就可以正常运行:

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

然后,我们可以成功访问和测试该应用程序。但是,如果我们在后台启动它,它不仅会停止运行,而且我们似乎无法在没有将其带到前台

[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.

我是不是启动不当?有没有办法让作业继续运行,即使它在后台?我需要将其作为守护进程启动,nohup然后注销,但除非它仍然是前台进程,否则我似乎无法让它成功运行,但这是不可行的。

答案1

似乎正在等待输入的后台作业被停止在大多数环境中。

来自维基百科关于 Unix 作业控制的页面

尝试读取或写入控制终端的后台进程将收到 SIGTTIN(用于输入)或 SIGTTOU(用于输出)信号。这些信号默认会停止进程,但也可以采用其他方式处理。

并且来自罗格斯大学关于 Unix 中级使用的页面

如果需要输入,后台运行的作业将停止。无法为后台作业提供输入,因此请确保所有必要的输入都可供其使用。

解决方案我们只是更新了 Java 进程以接受一个可选参数,这将导致主线程无限期休眠,而不是等待输入。我们有一个关闭钩子可以SIGTERM/SIGINT适当地处理信号:

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

相关内容