如何守护Java程序?

Ric*_*aca 72 java daemon process

我有一个Java程序,我想在Linux系统上守护进程.换句话说,我想开始在shell中运行它,并在我退出后继续运行它.我也希望能够干净地停止这个程序.

我发现这篇文章使用shell脚本和Java代码的组合来完成这个技巧.它看起来不错,但如果可能的话,我想要更简单的东西.

在Linux系统上守护Java程序的首选方法是什么?

Bah*_*aid 38

Apache Commons Daemon将运行您的Java程序作为Linux守护程序或WinNT服务.


Var*_*han 32

如果您不能依赖其他地方引用的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 </dev/null > $logfile 2>&1
Run Code Online (Sandbox Code Playgroud)

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());
}
Run Code Online (Sandbox Code Playgroud)

  • 不需要Java来编写PID,脚本也可以这样做(echo $!> /var/run/my.pid)另外,因为通常只有root可以写入/ var/run你可以拥有shell脚本以root身份运行,守护程序以另一个用户身份运行. (9认同)
  • 此外,让Java编写pid文件/锁定文件的基本原理是知道守护程序的初始化阶段是否成功完成(通过在该阶段结束时写入). (3认同)

Ben*_*rdy 24

我经常发现自己编写的脚本或命令行基本上是这样的,如果我想:

  1. 运行一个免疫sighups的程序
  2. 这与产生它的外壳完全断开,并且
  3. 从stderr和stdout生成一个日志文件,其内容也会显示,但是
  4. 允许我停止查看正在进行的日志并执行其他操作而不会中断正在运行的进程

请享用.

nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
Run Code Online (Sandbox Code Playgroud)

  • 一旦系统出现故障或崩溃,这将无法启动服务. (5认同)

S.L*_*ott 15

我更喜欢nohup命令.博客文章说有更好的方法,但我认为它们不够好.


Joh*_*n T 5

您可以尝试Java Service Wrapper,社区版是免费的,可以满足您的需求.

  • 你怎么知道它符合他的需求?根据其许可证,Java Service Wrapper不能免费用于商业用途:http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html (3认同)

col*_*ini 5

我在 Ubuntu 上的首选方法是使用 libslack“守护进程”实用程序。这就是 Jenkins 在 Ubuntu 上使用的方法(这也是我产生这个想法的地方)。我已经将它用于基于 Jetty 的服务器应用程序,并且运行良好。

当您停止守护进程时,它会通知 JVM 关闭。此时,您可以通过使用 Runtime.addShutdownHook() 注册关闭挂钩来执行关闭/清理代码。


归档时间:

查看次数:

93987 次

最近记录:

7 年,4 月 前