我們有一個使用 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
看來後台作業正在等待輸入被停止在大多數環境中。
嘗試讀取或寫入其控制終端的後台程序會收到 SIGTTIN(用於輸入)或 SIGTTOU(用於輸出)訊號。這些訊號預設停止進程,但也可以透過其他方式處理。
如果需要輸入,後台運行的作業將停止。無法將輸入提供給背景作業,因此請確保所有必要的輸入都可供其使用。
作為解決方案我們只是更新了 Java 進程以接受一個可選參數,該參數將導致主執行緒無限期地休眠,而不是等待輸入。我們有一個關閉鉤子可以SIGTERM/SIGINT
適當地處理訊號:
if (args.length >= 0 && StringUtils.equals(args[0], "daemon")) {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}