ActiveMQ фактически не соблюдает ограничения памяти

Я пытаюсь настроить ActiveMQ для использования ограничений памяти и управления потоком производителя, чтобы не видеть поведение зависания, которое можно увидеть, когда вы пытаетесь отправить сообщение, когда не хватает памяти. Я следил за документацией на странице Producer Flow Control, Мои блоки производителей и 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>

И затем в одном из моих методов инициализации кода я установил следующее:

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 для ограничения использования памяти.


person RobV    schedule 14.03.2013    source источник


Ответы (3)


Вы пытались настроить своего брокера напрямую с помощью XML-файла? Вы можете сделать это следующим образом (извлечение из официальный пример Java):

Брокер BrokerService = BrokerFactory.createBroker(configUrl);

Позже я попытаюсь получить работающий пример Spring.

person srodriguez    schedule 22.03.2013

Я пробовал это, но я не мог решить, что я ищу, но я, наконец, получил ссылку ниже, в которой есть полная информация.

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>
person Gautam    schedule 13.08.2015

Для тех, кто ищет, как программно управлять лимитами брокера, вот пример:

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

Благодаря этому сообщению за отправную точку: Как установить Порт ActiveMQ в Spring Boot?

person emoralesgt    schedule 21.06.2019