Java程序应该监听什么才能成为一个优秀的Linux服务?

时间:2012-02-07 15:43:06

标签: java linux service daemon

在Linux中,您可以提供以下命令:

service <someService> start
service <someService> stop

与使用kill -9 <someService>杀死进程相反。正如我在之前的一个问题中所了解的那样,这是将进程发送到SIGTERM(前者)和SIGKILL(后者)之间的区别。

那么如何将普通JAR或WAR作为可以使用这些命令启动和停止的服务/守护进程“注册”(和编码)?我认为Java必须有一些API来处理SIGTERM s?

提前致谢!

2 个答案:

答案 0 :(得分:35)

如果你只想运行一些关闭特定的代码,处理它的“正确的Java”方式不会使用信号,而是添加一个通用的“关闭钩子”,当你的应用程序即将终止时它会运行。这是Java有时会遇到的最不常见的问题之一。 (由于并非所有平台都支持SIGINT,因此在Java中,没有平台支持SIGINT。)

不幸的是,您在ShutdownHook中没有获得太多上下文,但它可能仍然有用:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    public void run()
    {
        // cleanup
    }
}));

如果你真的需要区分收到的信号,或者你想要支持Java通常忽略的信号(如USR1),或者你想根据信号中止关机,那么{{1}不幸的是,对你来说将是无用的。

使用ShutdownHook类,有一种不受支持的,记录不完整的方法来捕获Sun JVM中的信号。虽然它似乎是IBM JVM also supports this

,但这是可移植的

例如 - 您可以连接一个信号处理程序来监听sun.misc.SignalHandler重新加载您的服务器配置,该配置在SIGHUP脚本中设置为init.d动词:

reload

至于使用Signal.handle(new Signal("HUP"), new SignalHandler() { public void handle(Signal signal) { reloadConfiguration(); } }); 命令配置要控制的Java应用程序,您应该在system程序中编写一个启动它的shell脚本。这只需要回复init.dstart动词并采取适当的行动。例如,这可能是您的stop

/etc/init.d/my-java-program

您现在可以通过运行#!/bin/sh case "$1" in start) java /path/to/my/java/program.jar & echo $! > /var/run/my-java-program.pid ;; stop) if [ ! -f /var/run/my-java-program.pid ]; then echo "my-java-program: not running" exit 1 fi kill -TERM `cat /var/run/my-java-program.pid` ;; reload) if [ ! -f /var/run/my-java-program.pid ]; then echo "my-java-program: not running" exit 1 fi kill -HUP `cat /var/run/my-java-program.pid` ;; *) echo "Usage: /etc/init.d/my-java-program {start|stop|reload}" exit 1 ;; esac exit 0 启动应用程序,或者在CentOS上启动应用程序,也可以使用service my-java-program start`。

答案 1 :(得分:3)

您无法像在本机Unix程序中那样为纯Java中的不同信号定义信号处理程序。这意味着您不能遵循例如惯例。让程序在SIGHUP上重新加载其配置,并在SIGINTSIGTERM上执行干净关闭。

您可以做的是定义shutdown hook。它们在虚拟机将要关闭时运行,例如,收到SIGTERM后。这是一个例子:

Runnable myShutdownHook = new Runnable() {
    void run() {
        System.out.println("I'm melting! What a world...");
    }
};

Runtime.getRuntime().addShutdownHook(new Thread(myShutdownHook));