【问题标题】:ActiveMQ memory limit exceeded超出 ActiveMQ 内存限制
【发布时间】:2015-02-27 01:35:06
【问题描述】:

我尝试为以下行为配置 ActiveMQ:当代理超过其内存限制时,它应该将消息存储在持久性存储中。如果使用如下配置:

    BrokerService broker = new BrokerService();
    broker.setBrokerName("activemq");
    KahaDBPersistenceAdapter persistence = new KahaDBPersistenceAdapter();
    persistence.setDirectory(new File(config.getProperty("amq.persistenceDir", "amq")));
    broker.setPersistenceAdapter(persistence);
    broker.setVmConnectorURI(new URI("vm://activemq"));
    broker.getSystemUsage().getMemoryUsage().setLimit(64 * 1024 * 1024L);
    broker.getSystemUsage().getStoreUsage().setLimit(1024 * 1024 * 1024 * 100L);
    broker.getSystemUsage().getTempUsage().setLimit(1024 * 1024 * 1024 * 100L);
    PolicyEntry policyEntry = new PolicyEntry();
    policyEntry.setCursorMemoryHighWaterMark(50);
    policyEntry.setExpireMessagesPeriod(0L);
    policyEntry.setPendingDurableSubscriberPolicy(new StorePendingDurableSubscriberMessageStoragePolicy());
    policyEntry.setMemoryLimit(64 * 1024 * 1024L);
    policyEntry.setProducerFlowControl(false);
    broker.setDestinationPolicy(new PolicyMap());
    broker.getDestinationPolicy().setDefaultEntry(policyEntry);
    broker.setUseJmx(true);
    broker.setPersistent(true);
    broker.start();

但是,这不起作用。 ActiveMQ 仍然会消耗尽可能多的内存来存储完整队列。我还尝试删除 PolicyEntry,这会导致代理在达到内存限制后停止生产者。我在文档中找不到任何关于我做错的事情。

【问题讨论】:

  • 我将大约 10Gb 的消息放入队列中,发现该队列虽然超过了指定的内存限制约 7 次,但仍保持此因子不变,即不会抛出 OutOfMemoryException。将带有 -Xmx 标志的 JVM 限制为 512 mb 会导致 OOME。我认为,有问题,但至少我可以肯定,如果我给队列 1Gb,JVM 不会失败。

标签: activemq


【解决方案1】:

我们使用storeCursor 并将内存限制设置如下...这会将所有队列的内存量限制为 100MB...

   <destinationPolicy>
        <policyMap>
            <policyEntries>
                <policyEntry queue=">" producerFlowControl="false" memoryLimit="100mb">
                    <pendingQueuePolicy>
                        <storeCursor/>
                    </pendingQueuePolicy>
                </policyEntry>
            </policyEntries>
        </policyMap>
    </destinationPolicy>

确保您设置了您的政策应适用的“目的地”...在我的 XML 示例中,这是使用 queue="&gt;" 完成的,但您的示例使用的是 new PolicyMap()...尝试调用 policyEntry.setQueue("&gt;")应用于所有队列或将特定目的地添加到您的 PolicyMap 等。

查看此测试以获取完整示例...

https://github.com/apache/activemq/blob/master/activemq-unit-tests/src/test/java/org/apache/activemq/PerDestinationStoreLimitTest.java

【讨论】:

  • 使用存储光标。而且我不通过 XML 配置 ActiveMQ。
  • 这两个我都试过了:policyEntry.setPendingQueuePolicy(new StorePendingQueueMessageStoragePolicy()); policyEntry.setPendingDurableSubscriberPolicy(new StorePendingDurableSubscriberMessageStoragePolicy());并通过 XML 进行配置。不过没有任何帮助。
  • 不清楚您使用的是哪个光标...但是我们在使用 VM 光标时遇到了同样的问题,这解决了它...无论您是否使用 XML/Java 来配置它,潜在的问题听起来是一样的……我的例子展示了我们是如何解决它的……也许它不同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2019-11-07
  • 2012-05-05
相关资源
最近更新 更多