简体   繁体   中英

ActiveMQ does not actually respect memory limits

I'm trying to set up ActiveMQ to use memory limits and producer flow control so that I don't see the hang behaviour that can be seen when you try to send a message when there is insufficient memory. I have followed the documentation at Producer Flow Control , My producer blocks and Connection Configuration URI with little luck.

The problem I am running into is that these settings don't actually appear to be properly honored.

My ActiveMQ broker is set up like so in my Spring config (I have sanitized this slightly so may not be 100% valid Spring config):

<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>

And then in one of my codes init methods I set the following:

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

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

Yet when I run my code I still see things in my logs like the following:

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

So ActiveMQ appears to be blatantly flouting the set memory limit.

I still see the blocking behavior that can occur if you put a sufficiently large message into the queue and even OOM errors if I put a really large message into the queue.

How do I reliably configure ActiveMQ to limit its memory usage.

Ha you tried configure your broker directly with the xml file? You can do that like this (extract from the official Java example ):

BrokerService broker = BrokerFactory.createBroker(configUrl);

I'll try getting a running Spring example later

I have tried that but I could not resolved that what i am seeking but I finally got below link it has complete information

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

Thanks to above thread, I got solution. Above thread has good amount of information. I have change the activemq.xml as follows

<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>

For anyone looking how to manage programmatically the broker limits, here is an example:

    @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;
    }

Thanks to this post for the starting point: How to set ActiveMQ port in Spring Boot?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM