7

语境

我们想使用 Hazelcast 作为我们在 TomEE 中的 JCache 实现。由于我们不需要疯狂的性能,目前,我们希望将 Hazelcast 节点作为我们应用程序的一部分运行。

我们使用Hazelcast 3.7TomEE 7.0.1

问题

停止TomEE时,它会抱怨WARNING - The web application [APPLICATION_NAME] appears to have started a thread named [SOMENAME] but has failed to stop it. This is very likely to create a memory leak.几次,VM不会正常停止而是继续运行。

解决方法显然是在进程看起来空闲时立即终止进程。不用说,这让我们的开发人员和开发人员发疯了。

单独的 Hazelcast 节点

为了排除问题是由在 TomEE 中运行的 Hazelcast 节点引起的,我尝试启动一个独立的 Hazelcast 节点并将我们的应用程序更改为仅使用 Hazelcast 客户端连接到所述节点。行为保持不变。据我从几个网络搜索中可以看出,Hazelcast 客户端也启动了几个线程,以与服务器节点进行通信。

Hazelcast 的副本不会阻止 JVM 终止

这个问题不是Hazelcast 的重复,它阻止 JVM 终止,因为我们完全依赖 Hazelcasts JCache 实现。我们不Hazelcast直接访问实例,因此我们不能调用shutDownAll().

测试用例

在 GitHub 上创建了一个小测试用例来重现该问题。

问题

  • 我们可以在 Java EE 应用程序中使用 Hazelcast 作为 JCache 后端吗?
  • 我们需要做什么才能让应用程序正常停止?
  • 我们也可以将 Hazelcast 节点作为我们应用程序的一部分运行吗?如果不是:为什么这是一个坏主意?
4

2 回答 2

4

Hazelcast 使用自己的线程,它们并不总是守护进程,您可以确保通过像https://issues.apache.org/jira/browse/TOMEE-1723中的生产者那样关闭 hazelcast 实例(客户端或节点)

在 hazelcast 通过 CDI 扩展修复其实例的生命周期之前,它可能是您能做的最干净的。

注意:这也可以使用 tomee 内部服务器 API 提前启动实例,但在大多数情况下不需要

于 2016-08-22T13:14:07.790 回答
2

解决方案

rmannibucau回答为我指明了正确的方向。

我添加了一个 bean@Observes @Destroyed(ApplicationScoped.class)并调用Caching.getCachingProvider().close(). 这反过来会关闭底层的 Hazelcast 实例。

该解决方案还避免了与 Hazelcast 类的直接交互。依赖关系可以保持在runtime范围内。

我使用此解决方案向测试用例添加了一个分支。

于 2016-08-23T08:47:12.227 回答