java—如何干净地关闭嵌入式activemq artemis

jgovgodb  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(337)

我是javalite开源项目的维护人员。其中一部分称为异步,它是apacheactivemqartemis代理的简化前端。它的存在是为了更容易将artemis嵌入进程的内存中,同时也为处理“命令”增加了一层便利。我们已经在生产中使用了很多年,几乎没有任何问题。
但是,javalite项目本身有多次启动/停止代理的测试,并为不同的测试使用不同的示例。以下是 Async 以及测试的源代码。
如您所见,测试创建代理的新示例,使用它,然后停止它。
以下是启动和停止方法。
现在来回答问题。一般来说,在我的笔记本电脑和旧的ci环境上运行的构建测试都是成功的,没有任何问题。我的笔记本电脑和以前的ci服务器从来没有任何问题。但是,我们正在构建一个新的ci服务器,并且该测试在那里失败,出现随机数目的逻辑错误(测试条件)。有时它也会成功。除了硬件之外,在成功和失败的机器之间,一切都是相同的。出现故障的盒子只有两个cpu核(我的笔记本电脑有12个核)。
因此,在testasyncspec中,我们创建、启动和停止代理,似乎有些数据在代理的不同示例中随机溢出。
在同一个vm中创建/启动/停止/销毁artemis嵌入式服务器而不在多个示例之间发生冲突的最佳/最干净的方法是什么?

i34xakig

i34xakig1#

我将javalite加载到ide中,并为 AsyncSpec 测试你的链接。以下是我的观察结果。。。
我注意到的一件事是,你的一些测试可能会泄露消息。如果在代理停止之前有Assert的任何测试失败,那么该测试都可能泄漏,因为测试将在不停止代理的情况下终止。这将对随后的任何测试产生负面影响。你应该阻止你的经纪人在最后一个街区,也许在最后一个街区 @After 方法。在任何情况下,您都需要绝对确保无论测试中发生什么,代理都被停止。
你的测试也会泄露日志。使用以下命令创建嵌入式代理的日志目录:

Files.createTempDirectory("async").toFile().getCanonicalPath();

但是,您永远不会清理该目录。我在一个循环中运行了数千次测试迭代,它占用了超过200gb的磁盘空间。
我认为最重要的是,当您在测试中发送消息时,您以非持久的方式发送它们,这意味着它们将异步发送。但是,您的测试没有考虑到这一点,这可能会导致竞争条件,并最终导致Assert/测试失败。我看到了一些解决这个问题的方法。您可以以持久方式发送消息,这将同步完成。你可以设置 blockOnNonDurableSend=true 在嵌入式客户端的url上(在文档中讨论),这也将使发送消息同步。或者你可以加一些其他的 Wait.waitFor() 以确保在继续测试之前满足有意义的条件(尽管由于您使用的是异步消息侦听器,因此在大多数测试中无法检查消息计数)。
我也认为如果你使用 Wait.waitFor() 检查时 HelloCommand.counter() 如果你在关闭经纪人之前就这么做了。考虑到消息侦听器的异步特性,计数器的值和队列的消息计数之间可能存在短时间的差异。此外,让经纪人在 Wait.waitFor() 意味着消息侦听器不会过早停止。
当我第一次开始运行测试时,我可以在不到25次的运行中不断地重现失败。通过上面列出的更改,我可以运行12000次而没有失败。
最终,我看不出代理在这一点上有任何问题,只是测试的问题。

相关问题