Hazelcast可防止JVM终止

我们在遗留Java集群应用程序中使用Hazelcast 2.6.2。 当应用程序停止时,JVM不再终止。 它似乎是由Hazelcast线程没有被标记的守护进程引起的。 我没有找到通过Hazelcast API来标记它们守护进程的方法。

是否有推荐的解决方案来阻止Hazelcast阻止JVM终止?

问候

看看Hazelcast Javadocs ,我看到有一个shutdownAll(); 方法。 引用javadoc:

关闭此JVM上所有正在运行的Hazelcast实例,包括运行时的默认实例。 它不会关闭群集的所有成员,而只会关闭在此JVM上运行的成员。

如果你没有关闭它,我怀疑那里有非守护进程线程没有被终止,这将阻止JVM关闭。

在Tomcat中,我通过server.xml添加了一个生命周期监听器。

  

我的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关闭钩子应该足以解决这个问题,希望你也觉得它很有用。

这是一种检测JVM关闭的Tomcat独立方法。 它使用非守护程序线程轮询守护程序线程以检测JVM何时关闭(JVM自动关闭守护程序线程)。 轮询代码中的静态IS_SHUTDOWN标志,或者在此处内联对Hazelcast.shutdownAll()的调用。 请注意竞争条件,因为如果您尝试在启动之前关闭Hazelcast,那么它会在您的日志中引发exception。 例外并没有破坏任何东西,但它看起来很难看。

 /** * 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(); } } 

正如大家所说,hazelcastInstance.shutdownAll()就是解决方案。

但是,我想在Hazelcast中获得一个新function – 同时提供恶魔客户端。 有许多用例需要在应用程序结束时立即关闭缓存实例。