我有一个Java程序,我想在linux系统上守护进程。换句话说,我想开始在shell中运行它,并在我退出后继续运行它。我也希望能够干净地停止这个程序。
我发现this article使用shell脚本和Java代码的组合来完成这个技巧。它看起来不错,但如果可能的话,我想要更简单的东西。
在Linux系统上守护Java程序的首选方法是什么?
答案 0 :(得分:38)
Apache Commons Daemon将您的Java程序作为Linux守护程序或WinNT服务运行。
答案 1 :(得分:32)
如果您不能依赖Java Service Wrapper引用elsewhere(例如,如果您运行的是Ubuntu,它没有打包的SW版本)您可能希望以旧式方式执行此操作:让您的程序在/var/run/$progname.pid中编写其PID,并编写一个标准的SysV init脚本(例如,使用ntpd的脚本作为示例,它很简单)。最好使其符合LSB标准。
本质上,start函数测试程序是否已经运行(通过测试是否存在/var/run/$progname.pid,并且该文件的内容是正在运行的进程的PID),如果没有运行< / p>
logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
stop函数检查/var/run/$progname.pid,测试该文件是否是正在运行的进程的PID,验证它是否为Java VM(以免终止只重用PID的进程)从我的Java守护进程的死实例)然后杀死该进程。
调用时,我的main()方法将首先将其PID写入System.getProperty(“pidfile”)中定义的文件中。
但存在一个主要障碍:在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());
}
答案 2 :(得分:24)
我经常发现自己编写的脚本或命令行基本上就是这样,如果我想:
享受。
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
答案 3 :(得分:14)
我更喜欢nohup命令。博客文章说有更好的方法,但我认为它们不够好。
答案 4 :(得分:5)
您可以尝试Java Service Wrapper,社区版免费且符合您的需求。
答案 5 :(得分:4)
这取决于。如果它只是一次性的事情,我想守护它然后回家,但通常我等待结果,我可能会这样做:
nohup java com.me.MyProgram &
在命令行。要彻底杀死它,你有很多选择。您可能拥有SIGKILL的侦听器,或者在建立连接时侦听端口并关闭,并定期检查文件。差异方法有不同的弱点。如果它是用于生产的话,我会更多地考虑它,并且可能会将一个脚本放入/etc/init.d中,然后将其删除,并进行更复杂的关闭,例如tomcat所拥有的。
答案 6 :(得分:4)
我在Ubuntu上的首选方法是使用libslack'守护程序'实用程序。这就是Jenkins在Ubuntu上使用的东西(这是我的想法。)我已经将它用于基于Jetty的服务器应用程序并且运行良好。
当您停止守护程序进程时,它将通知JVM关闭。您可以通过使用Runtime.addShutdownHook()注册一个关闭挂钩来执行shutdown / cleanup代码。
答案 7 :(得分:2)
This问题是关于守护任意程序(不是特定于java的),因此一些答案可能适用于您的案例:
答案 8 :(得分:2)
DaemonTools: - 在UNIX https://cr.yp.to/daemontools.html
管理服务的更简洁方法从网址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 / service / vm现在应该正常运行!
答案 9 :(得分:0)
看看这里:
http://jnicookbook.owsiak.org/recipe-no-022/
表示基于JNI的示例代码。在这种情况下,你守护作为Java启动的代码,主循环在C中执行。但是也可以将main,守护进程的服务循环放在Java中。
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029
与JNI玩得开心!
答案 10 :(得分:0)
nohup java -jar {{your-jar.jar}} > /dev/null &
这可以解决问题。