我正在尝试将 ActiveMQ 设置为使用内存限制和生产者流控制,以便在内存不足时尝试发送消息时看不到挂起行为。我遵循了Producer Flow Control、My producer blocks和Connection 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>
然后在我的一个代码初始化方法中,我设置了以下内容:
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 以限制其内存使用。