我有一個Java程序,我想在Linux系統上守護進程。換句話說,我想開始在shell中運行它,並在退出後繼續運行它。我也希望能夠乾淨地停止程序。如何守護Java程序?
我發現this article它使用shell腳本和Java代碼的組合來完成這個技巧。它看起來不錯,但如果可能的話,我希望更簡單一些。
在Linux系統上守護Java程序的首選方法是什麼?
我有一個Java程序,我想在Linux系統上守護進程。換句話說,我想開始在shell中運行它,並在退出後繼續運行它。我也希望能夠乾淨地停止程序。如何守護Java程序?
我發現this article它使用shell腳本和Java代碼的組合來完成這個技巧。它看起來不錯,但如果可能的話,我希望更簡單一些。
在Linux系統上守護Java程序的首選方法是什麼?
Apache Commons Daemon將運行您的Java程序作爲Linux守護進程或WinNT服務。
你可以試試Java Service Wrapper,社區版是免費的,可以滿足你的需求。
你怎麼知道它滿足他的需求? Java Service Wrapper根據其許可證不能免費用於商業用途:http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html – Jared 2014-05-21 14:31:57
這取決於。如果它只是一個一次性的事情,我想守護進程,然後回家,但通常我等待結果,我可能會做:
nohup java com.me.MyProgram &
在命令行。要乾淨地殺死它,你有很多選擇。您可能擁有SIGKILL的偵聽器,或者在端口上偵聽並在建立連接時關閉,並定期檢查文件。差異方法有不同的弱點。如果它用於生產中,我會考慮更多,並且可能會在/etc/init.d中引入一個腳本,使腳本不被竊取,並且具有更復雜的關閉,比如tomcat的功能。
我經常發現自己寫腳本或命令行基本上是這樣的,如果我想:
享受。
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
如果你不能依靠Java Service Wrapper引elsewhere(例如,如果你在Ubuntu,其中有SW的無包裝的版本上運行),你可能想這樣做的老式方法:讓你的程序把它的PID寫在/var/run/$progname.pid中,然後在它周圍寫一個標準的SysV初始化腳本(例如用於ntpd的例子,這很簡單)。優選地,也使其符合LSB。
本質上,啓動函數測試程序是否已在運行(通過測試/var/run/$progname.pid是否存在,並且該文件的內容是正在運行的進程的PID),如果未運行
logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
上/var/run/$progname.pid停止功能檢查,測試,如果該文件是一個正在運行的進程的PID,驗證它是一個Java虛擬機(以便不殺一個過程,只需從Java守護進程的死實例中重用PID),然後殺死該進程。
當被調用時,我的main()方法將通過在System.getProperty(「pidfile」)中定義的文件中寫入其PID來啓動。
的一個主要障礙,雖然:在Java中,沒有簡單和標準的方式來獲得JVM上運行的進程的PID
以下是我想出了:
private static String getPid() {
File proc_self = new File("/proc/self");
if(proc_self.exists()) try {
return proc_self.getCanonicalFile().getName();
}
catch(Exception e) {
/// Continue on fall-back
}
File bash = new File("/bin/bash");
if(bash.exists()) {
ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID");
try {
Process p = pb.start();
BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
return rd.readLine();
}
catch(IOException e) {
return String.valueOf(Thread.currentThread().getId());
}
}
// This is a cop-out to return something when we don't have BASH
return String.valueOf(Thread.currentThread().getId());
}
This問題是關於daemonizing任意程序(不針對Java)這樣一些問題的答案可能適用於您的情況:
如果您喜歡新的東西,你可以嘗試Akuma。有關(很少)的信息,請參閱Kohsuke Kawaguchi's Blog。
我在Ubuntu上的首選方式是使用libslack'守護進程'實用程序。這就是Jenkins在Ubuntu上使用的(這是我的想法)。我已經將它用於基於Jetty的服務器應用程序,並且它運行良好。
當你停止守護進程時,它會發出關閉JVM的信號。您可以通過使用Runtime.addShutdownHook()註冊一個關閉鉤子來執行關閉/清除代碼。
的Daemontools: - 在UNIX https://cr.yp.to/daemontools.html管理服務
從URL https://cr.yp.to/daemontools/install.html 跟隨指令提到的還有,對於任何問題,請嘗試說明https://gist.github.com/rizkyabdilah/8516303
安裝守護程序工具,更清潔的方式創建一個文件在/etc/init/svscan.conf並添加下面的行(只需要cent-os-6.7)
start on runlevel [12345] stop on runlevel [^12345] respawn exec /command/svscanboot
#!/bin/bash echo starting VM exec java -jar /root/learning-/daemon-java/vm.jar
注: 用自己的Jar文件替換JAR。或任何Java類文件。
重新引導系統
svstat /服務/ VM應達和現在正在運行!。
到這裏看看:
http://jnicookbook.owsiak.org/recipe-no-022/
對於基於JNI示例代碼。在這種情況下,您將啓動爲Java的代碼和主循環在C中執行的守護進程守護進程。但是也可以將main,守護進程的服務循環放入Java中。
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029
有樂趣JNI!
請參閱http://stackoverflow.com/questions/407016/how-to-convert-an-existing-java-application-to-a-sys-v-service-daemon – 2009-02-10 23:15:44
嘗試`nohup java prog&` 。 – ceving 2012-07-09 14:47:21
在UNIX上管理服務的更簡潔的方法https://cr.yp.to/daemontools.html – Velu 2016-02-23 04:47:40