ActiveMQ 没有为队列释放磁盘存储空间

ActiveMQ not freeing up the disk storage for queue

当向 ActiveMQ 队列施加大量负载时,它似乎 enqueue/dequeue 消息是应该的,但存储仍然是满的。

这会导致生产者在一段时间后阻塞,当存储达到 100% 时,这反过来会导致应用程序停止响应请求。

这是我们正在使用的相关 activeMQ Spring 配置:

<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://activemq.apache.org/schema/core
                        http://activemq.apache.org/schema/core/activemq-core.xsd
                        http://activemq.apache.org/schema/core
                        http://activemq.apache.org/schema/core/activemq-core.xsd">

<!-- =====================================================
     Broker Configuration
     ===================================================== -->
<broker id="appEmbeddedBroker"
        xmlns="http://activemq.apache.org/schema/core"
        brokerName="${msg.embedded.broker.name}"
        persistent="true"
        dataDirectory="${msg.embedded.broker.data.directory}"
        useJmx="true" >

    <destinationPolicy>
        <policyMap>
            <policyEntries>
                <policyEntry topic=">" >
                    <pendingMessageLimitStrategy>
                        <constantPendingMessageLimitStrategy limit="1000"/>
                    </pendingMessageLimitStrategy>
                </policyEntry>
            </policyEntries>
        </policyMap>
    </destinationPolicy>

    <managementContext>
        <managementContext connectorPort="${msg.embedded.broker.jmx.port}" createConnector="false"/>
    </managementContext>

    <persistenceAdapter>
        <levelDB directory="${msg.embedded.broker.db.directory}" />
    </persistenceAdapter>

    <systemUsage>
        <systemUsage>
            <memoryUsage>
                <memoryUsage percentOfJvmHeap="10"/>
            </memoryUsage>
            <storeUsage>
                <storeUsage limit="${msg.embedded.broker.system.usage.store.usage}"/> <!-- Configured for 200Mb -->
            </storeUsage>
            <tempUsage>
                <tempUsage limit="${msg.embedded.broker.system.usage.temp.usage}"/> <!-- Configured for 40Mb -->
            </tempUsage>
        </systemUsage>
    </systemUsage>

    <plugins>
        <!-- Configure authentication; Username, passwords and groups -->
        <simpleAuthenticationPlugin anonymousAccessAllowed="false">
            <users>
                <authenticationUser username="app" password="${msg.embedded.broker.app.password}"
                                    groups="users"/>
            </users>
        </simpleAuthenticationPlugin>
    </plugins>

    <transportConnectors>
        <transportConnector name="tcp" uri="tcp://0.0.0.0:${msg.embedded.broker.port}?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>

    <shutdownHooks>
        <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
    </shutdownHooks>

</broker>


<!-- =====================================================
     Client Connections
     ===================================================== -->

<bean id="embeddedAmqConnectionFactory"  class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="appEmbeddedBroker" >
    <property name="brokerURL" value="${msg.embedded.broker.url}" />
    <property name="userName" value="${msg.embedded.client.app.username}" />
    <property name="password" value="${msg.embedded.broker.app.password}" />
</bean>

<bean id="embeddedAmqPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" >
    <property name="connectionFactory" ref="embeddedAmqConnectionFactory" />
    <property name="maxConnections" value="${msg.embedded.client.connection.pool.max}" />
</bean>

查询bean时:

$>get QueueSize EnqueueCount DequeueCount                                                                                  

#mbean = org.apache.activemq:brokerName=app-embedded,destinationName=the.queue.name.local,destinationType=Queue,type=Broker:

QueueSize = 0;


EnqueueCount = 17821;


DequeueCount = 17821;

并且:

#mbean = org.apache.activemq:brokerName=app-embedded,type=Broker:

StoreLimit = 209715200;


StorePercentUsage = 100;


TempLimit = 41943040;


TempPercentUsage = 0;

因此,问题是:为什么如果所有消息都已出队,我们仍然看到 100% 的存储使用率?

这可能有很多原因,具体取决于您的代理配置和使用情况。首先要检查您的 DLQ 的内容是什么,然后在控制台上查看保存消息的其他目的地。由于事物通过 KahaDB 日志传播的方式,它们可能会创建一个链,该链在您清除其他一些队列或回滚任何仍在进行中的事务等之前无法中断。

ActiveMQ 站点上有一个 guide,介绍了如何开始调试应该可以帮助您入门的情况。

也尝试 运行 最新的代理版本,这些组件中有一些修复程序试图解决这些情况。