带有JDBC持久性的java ActiveMQ会在代理上产生OutOfMemory
我使用的是ActiveMQ 5.16.0,broker以512MB堆大小(-Xms=512m -Xmx=512
)启动。
配置文件activemq.xml
如下所示:
<bean id="postgresql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/postgres?currentSchema=amq" />
<property name="username" value="..." />
<property name="password" value="..." />
</bean>
(...)
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="2 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="5 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
(...)
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" producerFlowControl="true" memoryLimit="50 mb" maxPageSize="100" maxBrowsePageSize="100" lazyDispatch="true"></policyEntry>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
我使用的是单生产者,它将500条持久消息推送到单个队列中,每条消息大约1MB。在producer完成消息的生成后,一切似乎都正常,在activemq_msgs
表中有500条记录可用,ActiveMQ web控制台显示大约9%的内存使用率,如果我的计算正确的话,这应该是正确的:
70% * 512MB = 358.4MB
-总可用内存70% * 50MB = 35MB
-单个队列的总可用内存35MB / 358.4MB * 100 = ~9%
-已使用内存
现在,当我重新启动代理时,问题就出现了。AMQ启动后不久,我遇到了一个例外:
org.postgresql.util.PSQLException: Ran out of memory retrieving query results.
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2255)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:122)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:122)
at org.apache.activemq.store.jdbc.adapter.DefaultJDBCAdapter.doRecoverNextMessages(DefaultJDBCAdapter.java:1081)
at org.apache.activemq.store.jdbc.JDBCMessageStore.recoverNextMessages(JDBCMessageStore.java:365)
at org.apache.activemq.store.ProxyMessageStore.recoverNextMessages(ProxyMessageStore.java:110)
at org.apache.activemq.broker.region.cursors.QueueStorePrefetch.doFillBatch(QueueStorePrefetch.java:127)
at org.apache.activemq.broker.region.cursors.AbstractStoreCursor.fillBatch(AbstractStoreCursor.java:476)
at org.apache.activemq.broker.region.cursors.AbstractStoreCursor.reset(AbstractStoreCursor.java:179)
at org.apache.activemq.broker.region.cursors.StoreQueueCursor.reset(StoreQueueCursor.java:166)
at org.apache.activemq.broker.region.Queue.doPageInForDispatch(Queue.java:2047)
at org.apache.activemq.broker.region.Queue.pageInMessages(Queue.java:2283)
at org.apache.activemq.broker.region.Queue.doBrowse(Queue.java:1183)
at org.apache.activemq.broker.region.Queue.expireMessages(Queue.java:957)
at org.apache.activemq.broker.region.Queue.access$100(Queue.java:108)
at org.apache.activemq.broker.region.Queue$2.run(Queue.java:152)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.OutOfMemoryError: Java heap space
at org.postgresql.core.PGStream.receiveTupleV3(PGStream.java:561)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2251)
... 23 more
我检查了PostgreSQL日志,注意到有一个SELECT
查询几乎检索整个表,所以看起来AMQ试图从表中加载所有内容,所以可能这就是OOM的原因:
LOG: execute <unnamed>: SELECT ID, MSG FROM ACTIVEMQ_MSGS WHERE CONTAINER=$1 AND ID < $2 AND ID > $3 AND XID IS NULL ORDER BY ID LIMIT 32767
DETAIL: parameters: $1 = 'queue://TEST', $2 = '501', $3 = '-1'
我尝试了一些目的地策略属性,比如:maxPageSize
,lazyDispatch
,但它似乎对这个问题没有任何影响
也许我做错了什么?我会很感激你的任何想法,谢谢
共 (0) 个答案