我有一个Java程序,我想在Linux系统上守护进程.换句话说,我想开始在shell中运行它,并在我退出后继续运行它.我也希望能够干净地停止这个程序.
我发现这篇文章使用shell脚本和Java代码的组合来完成这个技巧.它看起来不错,但如果可能的话,我想要更简单的东西.
在Linux系统上守护Java程序的首选方法是什么?
Apache Commons Daemon将运行您的Java程序作为Linux守护程序或WinNT服务.
如果您不能依赖其他地方引用的Java Service Wrapper(例如,如果您运行的是Ubuntu,它没有SW的打包版本)您可能希望以旧式方式执行此操作:让您的程序在/中编写其PID var/run/$ progname.pid,并围绕它编写一个标准的SysV init脚本(例如用于ntpd的脚本作为一个例子,它很简单).优选地,也使其符合LSB.
本质上,start函数测试程序是否已经运行(通过测试是否存在/var/run/$progname.pid,并且该文件的内容是正在运行的进程的PID),如果没有运行
logfile=/var/log/$progname.log pidfile=/var/run/$progname.pid nohup java -Dpidfile=$pidfile $jopts $mainClass $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()); }
我经常发现自己编写的脚本或命令行基本上是这样的,如果我想:
运行一个免疫sighups的程序
这与产生它的外壳完全断开,并且
从stderr和stdout生成一个日志文件,其内容也会显示,但是
允许我停止查看正在进行的日志并执行其他操作而不会中断正在运行的进程
请享用.
nohup java com.me.MyProgram &1 | tee logfile.log &
我更喜欢nohup命令.博客文章说有更好的方法,但我认为它们不够好.
您可以尝试Java Service Wrapper,社区版是免费的,可以满足您的需求.