Java 程序应该听什么,才能成为一个好的 Linux 服务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9179197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What should a Java program listen for, to be a good Linux service?
提问by IAmYourFaja
In Linux you can give the following commands:
在 Linux 中,您可以给出以下命令:
service <someService> start
service <someService> stop
As opposed to killing the process with kill -9 <someService>
. As I learned in an earlier question, this is the difference between sending the process a SIGTERM
(former) and a SIGKILL
(latter).
与使用kill -9 <someService>
. 正如我在之前的一个问题中了解到的,这是发送进程 a SIGTERM
(前者)和 a SIGKILL
(后者)之间的区别。
So how does one go about "registering" (and coding) an ordinary JAR or WAR as a service/daemon that can be started and stopped with those commands? I would imagine that Java must have some API for handling SIGTERM
s?
那么如何将一个普通的 JAR 或 WAR “注册”(和编码)为一个可以用这些命令启动和停止的服务/守护进程呢?我想 Java 必须有一些 API 来处理SIGTERM
s?
Thanks in advance!
提前致谢!
采纳答案by Edward Thomson
If you just want to run some shutdown specific code, the "proper Java" way to handle this would not use signals, but would instead add a generic "shutdown hook" that would run when your application was about to terminate. This is one of those least-common-denominator problems that Java sometimes suffers from. (Since not all platforms support SIGINT
, in Java, no platform supports SIGINT
.)
如果您只想运行一些特定于关闭的代码,那么处理此问题的“正确的 Java”方式将不使用信号,而是添加一个通用的“关闭挂钩”,该挂钩将在您的应用程序即将终止时运行。这是 Java 有时会遇到的那些最不常见的问题之一。(由于并非所有平台都支持SIGINT
,因此在 Java 中,没有平台支持SIGINT
。)
Unfortunately, you don't get much context in a ShutdownHook
, but it may still be useful:
不幸的是,您在 a 中没有获得太多上下文ShutdownHook
,但它可能仍然有用:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run()
{
// cleanup
}
}));
If you really need to distinguish between the signal received, or you want to support signals that Java normally ignores (like USR1
), or you want to abort shutdown based on a signal, then a ShutdownHook
will be mostly useless for you, unfortunately.
如果你真的需要区分接收到的信号,或者你想支持 Java 通常忽略的信号(比如USR1
),或者你想根据信号中止关闭,那么 aShutdownHook
对你来说几乎没有用,不幸的是。
There is a non-supported, poorly-documented way to capture signals in the Sun JVM, using the sun.misc.SignalHandler
class. This is questionably portable, though it appears that the IBM JVM also supports this.
在 Sun JVM 中,有一种不受支持的、记录不足的方法可以使用sun.misc.SignalHandler
该类来捕获信号。这值得怀疑,尽管IBM JVM似乎也支持此.
For example - you could hook up a signal handler to listen to SIGHUP
reload your server configuration, which was set up in the init.d
script as the reload
verb:
例如 - 您可以连接一个信号处理程序来监听SIGHUP
重新加载您的服务器配置,该配置在init.d
脚本中设置为reload
动词:
Signal.handle(new Signal("HUP"), new SignalHandler() {
public void handle(Signal signal)
{
reloadConfiguration();
}
});
As for configuring a Java application to be controlled using the system
command, you should write a shell script in init.d
program that starts it up. This simply needs to respond to the start
and stop
verbs and take the appopriate action. For example, this could be your /etc/init.d/my-java-program
:
对于配置使用system
命令控制的 Java 应用程序,您应该在init.d
启动它的程序中编写一个 shell 脚本。这只需要响应start
和stop
动词并采取适当的行动。例如,这可能是您的/etc/init.d/my-java-program
:
#!/bin/sh
case "" 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
You can now start your application by running /etc/init.d/my-java-program start
, or on CentOS, you can also use service my-java-program start`.
您现在可以通过运行来启动您的应用程序/etc/init.d/my-java-program start
,或者在 CentOS 上,您也可以使用 service my-java-program start`。
回答by Joni
You cannot define signal handlers for different signals in pure Java, like you would in a native Unix program. This means that you can't follow common conventions of e.g. having the program reload its configuration on SIGHUP
and do a clean shutdown on SIGINT
or SIGTERM
.
您不能像在原生 Unix 程序中那样在纯 Java 中为不同的信号定义信号处理程序。这意味着您不能遵循常见的约定,例如让程序重新加载其配置SIGHUP
并在SIGINT
或上执行干净的关闭SIGTERM
。
What you can do is define a shutdown hook. They are run when the virtual machine is going to shut down, e.g. after receiving SIGTERM
. Here's an example:
你可以做的是定义一个关闭钩子。它们在虚拟机将要关闭时运行,例如在收到SIGTERM
. 下面是一个例子:
Runnable myShutdownHook = new Runnable() {
void run() {
System.out.println("I'm melting! What a world...");
}
};
Runtime.getRuntime().addShutdownHook(new Thread(myShutdownHook));