Java 如何干净地关闭嵌入式ActiveMQ Artemis

Java 如何干净地关闭嵌入式ActiveMQ Artemis,java,activemq-artemis,Java,Activemq Artemis,我是开源项目的维护者。其中一部分被调用,它是ApacheActiveMQ Artemis代理的简化前端。它的存在是为了更容易将Artemis嵌入进程的内存中,同时也为处理“命令”增加了一层便利。我们已经在生产中使用了多年,几乎没有任何问题 但是,JavaLite项目本身具有多次启动/停止代理并使用不同实例进行不同测试的测试。异步的和 如您所见,测试创建代理的新实例,使用它,然后停止它 以下是方法和步骤 现在来回答问题。通常,在我的笔记本电脑和较旧的CI环境上,构建运行测试都会成功,不会出现问题。

我是开源项目的维护者。其中一部分被调用,它是ApacheActiveMQ Artemis代理的简化前端。它的存在是为了更容易将Artemis嵌入进程的内存中,同时也为处理“命令”增加了一层便利。我们已经在生产中使用了多年,几乎没有任何问题

但是,JavaLite项目本身具有多次启动/停止代理并使用不同实例进行不同测试的测试。异步的和

如您所见,测试创建代理的新实例,使用它,然后停止它

以下是方法和步骤

现在来回答问题。通常,在我的笔记本电脑和较旧的CI环境上,构建运行测试都会成功,不会出现问题。我的笔记本电脑和以前的CI服务器从未出现过任何问题。但是,我们正在构建一个新的CI服务器,该测试在那里失败,出现随机数目的逻辑错误(测试条件)。有时它也会成功。除了硬件,在成功和失败的机器之间,一切都是相同的。出现故障的机箱只有两个CPU核心(我的笔记本电脑有12个核心)

因此,在测试中,我们创建、启动和停止代理,似乎有些数据在代理的不同实例中随机流出


在同一个VM中创建/启动/停止/销毁Artemis嵌入式服务器而不在多个实例之间发生冲突的最佳/最干净的方法是什么?

我将JavaLite加载到我的IDE中,并为虚拟机重现了一些故障。以下是我的观察结果

我注意到的一件事是,您的一些测试可能会泄露代理。如果断言失败,那么在代理停止之前具有断言的任何测试都可能泄漏,因为测试将在不停止代理的情况下终止。这将对随后的任何测试产生负面影响。您应该在finally块中或者在
@After
方法中停止代理。在任何情况下,您都需要绝对确保无论测试中发生什么,代理都被停止

你的测试也会泄露日志。您可以使用以下方法创建嵌入式代理的日志目录:

Files.createTempDirectory(“异步”).toFile().getCanonicalPath();
但是,您永远不会清理该目录。我在一个循环中运行了数千次测试迭代,它占用了超过200GB的磁盘空间

我认为最重要的是,当您在测试中发送消息时,您将以非持久的方式发送它们,这意味着它们将异步发送。但是,您的测试没有考虑到这一点,这可能会导致竞争条件,并最终导致断言/测试失败。我看到了解决这个问题的两个选择。您可以以持久方式发送消息,这将同步完成。您可以在嵌入式客户端的URL(在中讨论)上设置
blockOnNonDurableSend=true
,这也将使发送消息同步。或者,您可以添加一些其他类型的
Wait.waitFor()
,以确保在继续测试之前满足有意义的条件(尽管由于使用异步消息侦听器,您无法在大多数测试中检查消息计数)

我还认为,如果您在检查
HelloCommand.counter()
时使用
Wait.waitFor()
,并且在关闭代理之前这样做,您的测试将更加健壮。鉴于消息侦听器的异步性质,计数器的值和队列的消息计数可能会在短时间内存在差异。此外,在
Wait.waitFor()
期间让代理处于运行状态将意味着消息侦听器不会过早停止

当我第一次开始运行测试时,我可以在不到25次的运行中始终重现失败。通过上面列出的更改,我能够运行12000次以上而不出现故障


最终,我看不到经纪人在这一点上有任何问题,只是测试问题。

@justin bertram,刚刚订阅了邮件列表,让我们在那里进行对话。@justin bertram,很抱歉问这个问题,但我没有经常使用邮件板,我该如何提问,我应该只向activemq.apache.org上的用户发送电子邮件吗?@justin bertram,我向activemq.apache.org上的用户发送了电子邮件,并在那里添加了更多上下文。谢谢你的帮助@justin bertram,邮件列表上的建议确实有帮助,我解决了问题,现在有了一个可复制的成功测试,感谢您的帮助!该目录已清理。我无意中共享了此代码的链接。所讨论的代码位于java8分支上。尽管如此,你为我指明了正确的方向,我消除了所有潜在的种族条件,这确实解决了问题。