【问题标题】:ActiveMQ not freeing up the disk storage for queueActiveMQ 没有为队列释放磁盘存储
【发布时间】:2016-11-13 22:47:37
【问题描述】:

当向 ActiveMQ 队列抛出大量负载时,它似乎按预期将消息入队/出队,但存储仍然满。

这会导致生产者在一段时间后阻塞,当存储达到 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% 的存储使用量?

【问题讨论】:

    标签: spring queue activemq


    【解决方案1】:

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

    ActiveMQ 站点上有一个guide,其中介绍了如何开始调试有助于您入门的情况。

    还可以尝试运行最新的代理版本,这些组件中已包含一些修复程序,可尝试解决此类情况。

    【讨论】:

    • 感谢@tim-bish 的回答。我查看了控制台,其他队列/主题似乎都没有保留消息,但存储空间仍然是满的。这是在另一次运行之后。此外,DLQ 未启用。我们在倒数第二个版本 (5.13.2) 中使用嵌入式 ActiveMQ 代理。还有一点需要注意的是,我们没有使用 KahaDB,而是使用了 LevelDB。
    • 不要使用LevelDB,它有很多问题并且没有上游志愿者来维护它。
    • 我们不久前解决了这个问题,但将这个答案标记为解决问题的答案,因为它实际上是填充空间的 DLQ。我们的配置使所有(或大部分)消息都进入 DLQ,即使它们已成功处理。
    猜你喜欢
    • 1970-01-01
    • 2010-09-24
    • 2021-05-15
    • 2011-04-06
    • 2012-01-31
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多