8

我的任务是调查为什么 db-*.log 文件没有被清除。

从我通过大量搜索发现的情况来看,一切都表明消息仍在队列中。我查看了所有已配置主题的队列中的 hawtio,队列大小为零。

据我了解,理论上 Enqueue 大小和 Dequeue 大小应该相同,但事实并非如此。似乎我的出列大小为 0。

我查看了这些主题,但没有清除它们的操作。

我希望能够清除所有消息,以便 kahadb 日志消失。

4

3 回答 3

4

我认为您指出了 ActiveMQ 本身的一个弱点:它不能保证消费者在消费消息时非常严格。

我们的 ActiveMQ (5.10.7) 也有类似的问题,因为 KahaDB 看起来像是“磁盘碎片”,我们注意到这可能来自消费者的至少两个问题:

案例一:慢消费者

我们的系统中有一个不能同时消费许多消息的消费者。如果只有一条未使用的消息留在 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 文件,我们可以看到仍然存在页面,甚至所有 QUEUES 中都没有消息。对于 TOPICS,我们停止使用持久订阅,那么存储也应该保持在 0%。

潜在的原因(这是一个假设,但有很强的信心)是某些消费的消息从未acknowledged正确处理过。我们之所以认为这是原因,是因为在日志中,我们仍然可以看到消息

"not removing data file: 12345 as contained ack(s) refer to referenced file: [12344, 12345]" 

例如,当消费者突然断开连接时(他们消费了一些消息,但在发送之前断开连接ack
,可能会发生这种情况。在我们的例子中,消息永不过期,那么这也可能是这种情况下的潜在问题。但是,尚不清楚设置过期是否会破坏“未确认”消息。因为我们不想丢失任何事件,所以这些特定队列没有过期时间。

根据您的问题,看来您属于第二种情况,那么我们的解决方案是:

  1. 确保没有更多的生产者/消费者连接到 ActiveMQ
  2. 确保所有队列和持久主题为空
  3. 删除 KahaDB 存储中的所有文件(从文件系统中)
  4. 重启 ActiveMQ(新鲜)

不幸的是,我们没有找到更好的方法来处理这些案例,如果其他人有更好的选择,我们很乐意知道。

本文还可以为您提供一些解决方案(例如为 ActiveMQ.DLQ 队列设置过期策略)。

于 2016-07-27T16:23:08.423 回答
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
于 2016-07-22T01:12:56.927 回答
0

作为替代方案:一旦您发现哪个队列导致日志存在,您可以将其映射到它自己的 KahaDB,如此处所述http://activemq.apache.org/kahadb.html

于 2016-09-10T21:15:50.863 回答