我们正在使用具有以下配置的ActiveMQ 5.6: - 流量控制 - 主题内存限制1MB - 启用镜像队列(未定义显式虚拟主题)
有持久消息被发送到队列QueueA
。显然,此消息被复制到Mirror.QueueA
,这是一个非持久且自动创建的主题。
关于这个话题,没有消费者。如果偶尔有消费者,他们就是非持久用户。
过了一会儿,生产者阻止,我们收到以下错误:
Usage Manager memory limit reached for topic://Mirror.QueueA
根据包含various sources的ActiveMQ documentation,在没有持久订阅者的主题中的消息将被删除,这是我想要的和预期的。但事实显然并非如此。
有one related StackOverflow question但已接受的解决方案建议使用流控制但禁用磁盘假脱机:
这不会使用磁盘,并在命中memoryLimit时阻止生成器。
但我不想阻止生产者,因为他们会无限期地阻止,因为没有消费者的到来。为什么这些消息会被保留?
我看到几个选项: - 这是一个错误,可能在以后的AMQ版本中修复 - 这个配置问题(我不知道如何解决它) - 当内存限制被命中时,有一些选项可以简单地删除最旧的消息(我无法找到任何此类选项)
我希望有人可以提供帮助!
谢谢,
∥焦
[更新]
虽然我们已经在现场部署5.6版本,但我目前在具有相同配置的5.8安装AMQ上运行相同的耐久性/负载测试。现在,我已经在5.6系统上发送了10次消息而没有任何问题。我会让这个测试在晚上甚至是接下来的几天运行,看看是否有其他限制。
答案 0 :(得分:2)
确定,
如之前的更新中所述,我在5.8安装ActiveMQ上运行相同的laod测试,其配置相同,导致存储超标。
这是在将大约450个事务发送到3个队列,主题内存限制为1MB之后发生的。您甚至可以观察KahaDB数据库文件的大小增长。
使用AMQ 5.8,我在4天后停止了负载测试,导致发送了大约280.000个事务。没有存储问题,没有卡住的制作人和KahaDB文件一直保持大致相同的大小。
所以,尽管我不能肯定这是ActiveMQ 5.6中的一个错误,但5.8显然表现得与预期和记录不同。没有订户注册时,它不会持久地在镜像队列中存储消息。
对于AMQ 5.6的现有安装,我们使用了一点点黑客来避免更改应用程序代码。
<destinations>
XML标记在配置启动时定义了一个主题。在使用通配符的地方,我们只使用了像all-device
这样的硬编码名称。遗憾的是,下一步需要这样做:<compositeQueue>
部分中定义了一个<destinationInterceptors>
,它将所有消息(<forwardTo>
)的副本从实际(镜像)队列路由到一个主题。此主题需要提前定义或手动创建,因为只需定义compositeQueue
也不会创建主题。另外,你不能使用总结一下,看起来有点像这样:
<destinations>
<topic name="Mirror.QueueA.all-devices" physicalName="Mirror.all-devices" />
</destinations>
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="QueueA.*" forwardOnly="false">
<forwardTo>
<topic physicalName="Mirror.QueueA.all-devices" />
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
希望这会有所帮助。这&#34; hack&#34;
。在某些情况下可能无法实现,但由于我们从未在单个Mirror主题上使用过,所以这是可能的。