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

IAm*_*aja 27 java linux service daemon

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

service <someService> start
service <someService> stop
Run Code Online (Sandbox Code Playgroud)

而不是杀死过程kill -9 <someService>.正如我在之前的一个问题中所了解到的,这是发送进程a SIGTERM(前者)和SIGKILL后者(后者)之间的区别.

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

提前致谢!

Edw*_*son 35

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

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

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    public void run()
    {
        // cleanup
    }
}));
Run Code Online (Sandbox Code Playgroud)

如果你真的需要区分收到的信号,或者你想要支持Java通常忽略的信号(比如USR1),或者你想根据信号中止关机,那么很ShutdownHook遗憾,对你来说,a 将是无用的.

使用sun.misc.SignalHandler该类,有一种不受支持的,记录不完整的方法来捕获Sun JVM中的信号.这是可移植的,尽管IBM JVM似乎也支持这一点.

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

Signal.handle(new Signal("HUP"), new SignalHandler() {
    public void handle(Signal signal)
    {
        reloadConfiguration();
    }
});
Run Code Online (Sandbox Code Playgroud)

至于使用该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
Run Code Online (Sandbox Code Playgroud)

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