ActiveMQ实际上并不尊重内存限制

时间:2013-03-14 21:03:16

标签: java jms activemq

我正在尝试设置ActiveMQ以使用内存限制和生产者流控制,这样当您尝试在内存不足时发送消息时,我看不到可以看到的挂起行为。我已经按照Producer Flow ControlMy producer blocksConnection Configuration URI上的文档进行了操作,但运气不佳。

我遇到的问题是这些设置实际上看起来并没有得到恰当的尊重。

我的ActiveMQ代理在我的Spring配置中就像这样设置了(我已经稍微清理了这个,所以可能不是100%有效的Spring配置):

<bean id="broker" class="org.apache.activemq.broker.BrokerService"
    init-method="start">
    <property name="brokerName" value="broker" />
    <property name="persistent" value="false" />
    <property name="useJmx" value="true" />
    <property name="managementContext" ref="mgmtContext" />
    <property name="transportConnectorURIs">
        <list>
            tcp://localhost:1234?jms.prefetchPolicy.queuePrefetch=0&jms.useAsyncSend=false&jms.alwaysSyncSend=true
        </list>
    </property>
        <property name="destinations">
            <list>
                <bean class="org.apache.activemq.command.ActiveMQQueue">
                    <property name="physicalName" value="requests"></property>
                </bean>
                <bean class="org.apache.activemq.command.ActiveMQQueue">
                    <property name="physicalName" value="responses"></property>
                </bean>
            </list>
    </property>
</bean>

然后在我的一个代码init方法中,我设置了以下内容:

broker.getSystemUsage().setSendFailIfNoSpace(true);
broker.getSystemUsage().setSendFailIfNoSpaceAfterTimeout(5000);

// Limit memory usage to 10MB
broker.getSystemUsage().getMemoryUsage().setLimit(10 * 1024 * 1024);

然而,当我运行我的代码时,我仍然会在日志中看到如下内容:

2013-Mar-14 14:47:31.538 GMT-06:00 DEBUG [ActiveMQ Transport: tcp:///127.0.0.1:45846@18086] [org.apache.activemq.usage.Usage:fireEvent] [Usage.java:245] [] [] [] - Main:memory: usage change from: 5640% of available memory, to: 0% of available memory

所以ActiveMQ似乎公然蔑视设定的内存限制。

如果您将足够大的消息放入队列,我仍然会看到阻塞行为,如果我将非常大的消息放入队列,甚至会出现OOM错误。

如何可靠地配置ActiveMQ以限制其内存使用量。

3 个答案:

答案 0 :(得分:0)

您尝试使用xml文件直接配置代理吗? 你可以这样做(摘自official Java example):

BrokerService broker = BrokerFactory.createBroker(configUrl);

我将尝试稍后运行一个正在运行的Spring示例

答案 1 :(得分:0)

我已经尝试了但是我无法解决我正在寻找但我终于得到以下链接它有完整的信息

http://blogs.sourceallies.com/2014/10/activemq-memory-tuning/

感谢上面的帖子,我得到了解决方案。 上面的线程有很多信息。 我已经更改了activemq.xml,如下所示     

<systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage limit="2048 mb"/>
                    <!--Earlier it use to be 
                    <memoryUsage limit="64 mb"/>
                    -->
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>

答案 2 :(得分:0)

对于希望通过编程方式管理经纪人限额的任何人,这是一个示例:

    @Bean
    public BrokerService broker()
            throws Exception {
        final BrokerService broker = new BrokerService();
        broker.addConnector("tcp://localhost:61616");
        broker.addConnector("vm://localhost");
        broker.setPersistent(false);
        broker.getConsumerSystemUsage().getMemoryUsage().setLimit(100 * 1024);
        broker.getConsumerSystemUsage().getStoreUsage().setLimit(1024 * 1024);
        broker.getConsumerSystemUsage().getTempUsage().setLimit(100 * 1024);
        return broker;
    }

感谢这篇文章的出发点: How to set ActiveMQ port in Spring Boot?