我们在传统Java集群应用程序中使用Hazelcast 2.6.2。当应用程序停止时,JVM不再终止。它似乎是由Hazelcast线程没有被标记的守护进程引起的。我没有找到通过Hazelcast API来标记守护进程的方法。
是否有建议的解决方案来阻止Hazelcast阻止JVM终止?
此致
答案 0 :(得分:2)
查看Hazelcast Javadocs,我发现有shutdownAll();
方法。引用javadocs:
关闭此JVM上所有正在运行的Hazelcast实例,包括运行时的默认实例。它不会关闭集群的所有成员,只会关闭在此JVM上运行的成员。
如果你没有关闭它,我怀疑那里有非守护程序线程没有被终止,这将阻止JVM关闭。
答案 1 :(得分:1)
在Tomcat中,我通过server.xml添加了一个生命周期监听器。
<Listener className="com.mycompany.StartupHandler" DEBUG="false"/>
My StartupHandler.class放在$ TOMCAT_HOME / lib /的一个jar中,它包含这个片段,当检测到Tomcat关闭时触发Hazelcast关闭:
public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
String eventType = lifecycleEvent.getType();
if (eventType.equals(Lifecycle.BEFORE_STOP_EVENT)) {
com.hazelcast.core.Hazelcast.shutdownAll();
}
}
其他Web服务器应该有类似的关闭挂钩,您可以自动调用Hazelcast.shutdownAll()。
有关同一主题的原始Hazelcast主题,请参阅https://github.com/hazelcast/hazelcast/issues/718。感谢此处提示调用Hazelcast.shutdownAll()。这个想法加上我的Tomcat关闭钩子应该足以解决这个问题,希望你也觉得它很有用。
答案 2 :(得分:0)
这是一种检测JVM关闭的Tomcat独立方法。它使用非守护程序线程轮询守护程序线程以检测JVM何时关闭(JVM自动关闭守护程序线程)。轮询代码中的静态IS_SHUTDOWN标志,或在此处内联对Hazelcast.shutdownAll()的调用。请注意竞争条件,因为如果您尝试在启动之前关闭Hazelcast,那么它会在您的日志中引发异常。例外并没有破坏任何东西,但它看起来很难看。
/**
* Non-Daemon thread monitors a sacrificial, low-priority, daemon thread
* to detect when JVM is shutting down, so shutdown hooks can be invoked.
* @author justin.cranford
*/
public class ThreadUtil {
public static boolean IS_SHUTDOWN = false; // threads can poll this flag, or inline below where flag is set
private static final Thread DAEMON_THREAD = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(Long.MAX_VALUE); // sleep forever
} catch(Exception e) {}
}
}
};
private static final Thread NONDAEMON_THREAD = new Thread() {
public void run() {
while (true) {
if (!DAEMON_THREAD.isAlive()) { // poll forever, until daemon thread dies
ThreadUtil.IS_SHUTDOWN = true;
return;
}
try {
Thread.sleep(1000); // poll every 1000msec = 1sec
} catch(Exception e) {}
}
}
};
static {
DAEMON_THREAD.setName("ShutdownMonitorNonDaemonThread");
DAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
DAEMON_THREAD.setDaemon(true);
DAEMON_THREAD.start();
try {
Thread.sleep(3000); // wait 3000msec = 3sec before monitoring
} catch(Exception e) {}
NONDAEMON_THREAD.setName("ShutdownMonitorDaemonThread");
NONDAEMON_THREAD.setPriority(Thread.MIN_PRIORITY);
NONDAEMON_THREAD.setDaemon(false);
NONDAEMON_THREAD.start();
}
}
答案 3 :(得分:0)
正如大家所说,hazelcastInstance.shutdownAll()就是解决方案。
但是,我想在Hazelcast中获得一个新功能 - 同时提供恶魔客户端。有许多用例需要在应用程序结束后立即关闭缓存实例。