问题:Java程序要监听什么,才能成为好的Linux服务?

在 Linux 中,您可以发出以下命令:

service <someService> start
service <someService> stop

而不是用kill -9 <someService>杀死进程。正如我在前面的问题中了解到的,这是发送进程SIGTERM(前)和SIGKILL(后)之间的区别。

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

提前致谢!

解答

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

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

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

如果你真的需要区分接收到的信号,或者你想支持Java通常忽略的信号(如USR1),或者你想根据信号中止关闭,那么不幸的是,ShutdownHook对你来说几乎没有用处。

使用sun.misc.SignalHandler类在 Sun JVM 中捕获信号有一种不受支持的、记录不充分的方法。这是可移植的,尽管IBM JVM 似乎也支持这个。

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

Signal.handle(new Signal("HUP"), new SignalHandler() {
    public void handle(Signal signal)
    {
        reloadConfiguration();
    }
});

至于使用system命令来配置一个Java应用程序被控制,你应该在init.d程序中编写一个shell脚本来启动它。这只需要响应startstop动词并采取适当的行动。例如,这可能是您的/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

您现在可以通过运行/etc/init.d/my-java-program start来启动您的应用程序,或者在 CentOS 上,您也可以使用 service my-java-program start`。

Logo

更多推荐