我的任务是调查db - * .log文件没有清除的原因。
通过大量搜索我发现,所有内容都指向队列中的消息。我在所有已配置主题的队列中查看了hawtio,队列大小为零。
根据我的理解,理论上的入队大小和出队大小应该是相同的,但他们并非如此。似乎我的Dequeue大小为0。
我已经查看了主题,并且没有清除它们的操作。
我希望能够清除所有邮件,以便kahadb日志消失。
答案 0 :(得分:2)
我认为你指出了ActiveMQ本身的一个弱点:它不能保证消费者在消费消息时非常严格。
我们的ActiveMQ(5.10.7)也有类似的问题,因为看起来KahaDB看起来像是一个“磁盘碎片”,我们注意到这可能至少来自消费者的两个问题:
案例1:消费者缓慢
我们的系统中有一个消费者,它不能同时消费许多消息。如果只有一个未消耗的消息留在kahaDB页面中,它将保留整个页面(所有其他消息已经被消费并被确认)。 为了防止KahaDB存储达到100%(这会降低生产者的速度),我们在另一个ActiveMQ实例临时队列中传输消息,如下所示:
from("activemqPROD:queue:BIG_QUEUE_UNCONSUMED")
.to("activemqTEMP:queue:TEMP_BIG_QUEUE");
然后推回他们:
from("activemqTEMP:queue:TEMP_BIG_QUEUE")
.to("activemqPROD:queue:BIG_QUEUE_UNCONSUMED");
另一种方法是将它们存储在文件系统上然后重新加载它们,但是你松开了JMS(和自定义)头文件。使用临时队列解决方案,您可以保留所有标题。
案例2:从未给予确认的消费者
有时即使我们进行上一次操作,即使所有未使用的队列都是空的,存储仍然高于0%。 通过查看KahaDB文件,我们可以看到在所有队列中仍然存在不再有消息的页面。 对于TOPICS,我们停止使用持久订阅,然后存储也应该保持在0%。
潜在原因(这是一个假设,但有很强的信心)是一些消费的消息永远不会acknowledged
正确。
我们之所以认为这是原因,是因为在日志中,我们仍然可以看到消息
"not removing data file: 12345 as contained ack(s) refer to referenced file: [12344, 12345]"
例如,当消费者断断续续地断开连接时(他们消耗了一些消息但在发送ack
之前断开连接),可能会发生这种情况。
在我们的情况下,消息永不过期,那么这也可能是本案的潜在问题。但是,不清楚设置过期是否会破坏“非确认”消息。
因为我们不想丢失任何事件,所以这些特定队列没有到期时间。
根据你的问题,它看起来你是第二种情况,那么我们的解决方案是:
不幸的是,我们没有找到更好的方法来管理这些案例,如果其他人有更好的选择,我们很乐意知道。
This article也可以为您提供一些解决方案(比如为ActiveMQ.DLQ队列设置过期策略)。
答案 1 :(得分:1)
将此日志配置添加到log4j.properties。然后你可以在kahadb.log中看到究竟是什么持有kahadb文件。
log4j.appender.kahadb=org.apache.log4j.RollingFileAppender
log4j.appender.kahadb.file=${activemq.base}/data/kahadb.log
log4j.appender.kahadb.maxFileSize=1024KB
log4j.appender.kahadb.maxBackupIndex=5
log4j.appender.kahadb.append=true
log4j.appender.kahadb.layout=org.apache.log4j.PatternLayout
log4j.appender.kahadb.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
log4j.logger.org.apache.activemq.store.kahadb.MessageDatabase=TRACE, kahadb
答案 2 :(得分:0)
作为替代方案:一旦您发现哪个队列导致日志存在,您可以将其映射到自己的KahaDB,如此处所述http://activemq.apache.org/kahadb.html