嵌入式ActiveMQ Classic Broker未上报tempStorageUsage且磁盘满报错
实现ActiveMQ Classic KahaDB tempStore使用量上报的方案
问题根源
你遇到的brokerView使用率显示0%的问题,是因为KahaDB自动创建的tempStore属于其内部独立的SystemUsage实例,并未纳入Broker全局的SystemUsage统计范畴,导致监控面板无法直接展示其使用情况。当tempStore磁盘耗尽时,会触发异步写入线程关闭的异常。
以下是三种可行的tempStore使用量上报方案:
1. 通过JMX直接采集tempStore指标
KahaDB的tempStore使用情况已通过JMX暴露,可直接获取对应MBean的属性:
- MBean路径:
org.apache.activemq:type=Broker,brokerName=<你的Broker名称>,service=KahaDBStore - 核心属性:
TempStoreUsage(对应SystemUsage对象),可获取usedMB、limitMB、percentUsage等关键指标
示例代码(Java JMX客户端):
import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class TempStoreMonitor { public static void main(String[] args) throws Exception { // 替换为你的Broker JMX地址 JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); JMXConnector connector = JMXConnectorFactory.connect(url); MBeanServerConnection mBeanServer = connector.getMBeanServerConnection(); // 替换为你的Broker名称 ObjectName kahadbMBean = new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,service=KahaDBStore"); // 获取tempStore的使用率百分比 Double percentUsage = (Double) mBeanServer.getAttribute(kahadbMBean, "TempStoreUsage"); // 获取已用和限制大小(MB) Long usedMB = (Long) mBeanServer.getAttribute(kahadbMBean, "TempStoreUsage.usedMB"); Long limitMB = (Long) mBeanServer.getAttribute(kahadbMBean, "TempStoreUsage.limitMB"); System.out.printf("tempStore使用情况: %.2f%%, 已用%dMB, 限制%dMB%n", percentUsage, usedMB, limitMB); connector.close(); } }
2. 自定义Broker插件实现监控上报
通过实现Broker插件,可在Broker内部直接采集tempStore数据,并上报到日志、监控系统(如Prometheus、Zabbix等):
import org.apache.activemq.broker.Broker; import org.apache.activemq.broker.BrokerFilter; import org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter; import org.apache.activemq.util.SystemUsage; import java.util.Timer; import java.util.TimerTask; public class TempStoreMonitorPlugin extends BrokerFilter { private SystemUsage tempStoreUsage; private Timer monitorTimer; public TempStoreMonitorPlugin(Broker next) { super(next); } @Override public void start() throws Exception { super.start(); // 获取KahaDB持久化适配器 KahaDBPersistenceAdapter kahadbAdapter = (KahaDBPersistenceAdapter) getBroker().getPersistenceAdapter(); tempStoreUsage = kahadbAdapter.getTempStoreUsage(); // 定时采集上报(每30秒一次) monitorTimer = new Timer(true); monitorTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { double percent = tempStoreUsage.getPercentUsage(); long used = tempStoreUsage.getUsage().getUsed() / (1024 * 1024); long limit = tempStoreUsage.getUsage().getLimit() / (1024 * 1024); // 这里替换为你的上报逻辑:打印日志、推送监控指标等 System.out.printf("[TempStore监控] 使用率: %.2f%%, 已用: %dMB, 总限制: %dMB%n", percent, used, limit); } }, 0, 30000); } @Override public void stop() throws Exception { if (monitorTimer != null) { monitorTimer.cancel(); } super.stop(); } }
然后在嵌入式Broker启动时注册插件:
import org.apache.activemq.broker.BrokerService; public class EmbeddedBroker { public static void main(String[] args) throws Exception { BrokerService broker = new BrokerService(); // 注册自定义监控插件 broker.setPlugins(new TempStoreMonitorPlugin(broker)); // 其他Broker配置(KahaDB、SystemUsage等) broker.start(); } }
3. 扩展KahaDB日志输出(快速排查用)
若仅需临时排查,可修改KahaDB的日志配置,开启org.apache.activemq.store.kahadb的DEBUG级别日志,此时KahaDB会定期输出tempStore的使用情况,例如:
DEBUG [KahaDBStore] TempStore usage: 50MB of 1000MB used
内容的提问来源于stack exchange,提问作者R Lawless
相关产品推荐
相关产品推荐

