我们面临一个奇怪的问题,其中一些随机队列的activemq消费者正在减少,直到它们变为0,之后它们无法恢复。 一旦发生这种情况,我们必须再次重新部署消费者应用程序以开始处理。 我们一直在努力解决这个问题,但无法找出根本原因。
activemq broker版本5.14.5
以下是连接配置。
<bean id="activeMQIconnectConnectionFactory" class="test.ActiveMQIconnectConnectionFactory">
<property name="brokerURL" value="failover:(tcp://localhost:61616)"/>
<property name="prefetchPolicy" ref="prefetchPolicy"/>
<property name="redeliveryPolicy" ref="redeliveryPolicy"/>
<property name="trustAllPackages" value="true"/>
<!-- http://activemq.apache.org/consumer-dispatch-async.html
The default setting is dispatchAsync=true
If you want better thoughput and the chances of having a slow consumer are low, you may want to change this to false.
-->
<property name="dispatchAsync" value="true"/>
<!--
whether or not timestamps on messages should be disabled or not. If you disable them it adds a small performance boost.
Default is false
-->
<property name="disableTimeStampsByDefault" value="true"/>
<!-- http://activemq.apache.org/optimized-acknowledgement.html
This option is disabled by default but can be used to improve throughput in some circumstances as it decreases load on the broker.
-->
<property name="optimizeAcknowledge" value="true"/>
<!-- Default 300ms
For us, 5 sec.
-->
<property name="optimizeAcknowledgeTimeOut" value="5000"/>
<property name="useAsyncSend" value="true"/>
<property name="exceptionListener" ref="jmsExceptionListener"/>
</bean>
<bean id="testQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test.queue"/>
</bean>
<bean id="jmsProducerFactoryPool" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"
init-method="start">
<property name="connectionFactory" ref="activeMQIconnectConnectionFactory"/>
<property name="maxConnections" value="10"/>
<property name="maximumActiveSessionPerConnection"
value="1000"/>
<property name="createConnectionOnStartup" value="true"/>
</bean>
<bean id="jmsConsumerFactoryPool" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"
init-method="start">
<property name="connectionFactory" ref="activeMQIconnectConnectionFactory"/>
<property name="maxConnections" value="10"/>
<property name="maximumActiveSessionPerConnection" value="1000"/>
<property name="createConnectionOnStartup" value="true"/>
<property name="reconnectOnException" value="true"/>
<property name="idleTimeout" value="86400000"/>
</bean>
<bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="1"/>
<property name="queue" value="*"/>
</bean>
<bean id="prefetchPolicy" class="org.apache.activemq.ActiveMQPrefetchPolicy">
<property name="queuePrefetch" value="500"/>
</bean>
<bean id="jmsTemplate" class="com.minda.iconnect.jms.impl.TimedJmsTemplate">
<property name="connectionFactory" ref="jmsProducerFactoryPool"/>
<property name="defaultDestinationName" value="iconnect.queue"/>
<property name="deliveryPersistent" value="true"/>
<!-- I think this is ingored if explicitQosEnabled is not set -->
</bean>
<bean id="simpleMessageConverter" class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
<bean id="testProducer"
class="com.test.TestProducer">
<property name="consumerDestination" ref="testQueu"/>
<property name="jmsTemplate" ref="jmsTemplate"/>
<property name="messageConverter" ref="simpleMessageConverter"/>
</bean>
<bean id="testContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConsumerFactoryPool"/>
<property name="destination" ref="testS"/>
<property name="messageListener">
<bean class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="testConsumer"/>
<property name="defaultListenerMethod" value="process"/>
<property name="messageConverter" ref="simpleMessageConverter"/>
</bean>
</property>
<property name="concurrentConsumers" value="50"/>
<property name="maxConcurrentConsumers" value="100"/>
<property name="sessionTransacted" value="false"/>
<property name="autoStartup" value="true"/>
</bean>
</beans>
connectionFactory的类
public class ActiveMQIconnectConnectionFactory extends org.apache.activemq.ActiveMQConnectionFactory
{
private static final Logger LOG = LoggerFactory.getLogger(ActiveMQIconnectConnectionFactory.class);
@Override
public void setBrokerURL(String brokerURL)
{
// LOG when connecting to activemq
// using this setter to be sure it's only logged once
// See DJ-5780
LOG.info("ActiveMQ configured is: " + (DEFAULT_BROKER_URL.equals(brokerURL) ? "(default init setting) " : "") + brokerURL);
LOG.info("Connecting to ActiveMQ");
super.setBrokerURL(brokerURL);
}
}
直到现在我们一直在玩超时等参数但不是运气。 我们怀疑问题是由于某些连接问题或通过DMLC处理连接而发生的,但无法识别问题。非常感谢帮助!
答案 0 :(得分:0)
我认为您的问题是基于您的配置相互影响的Spring DMLC和AMQ行为的混合。
尝试更改:
<property name="optimizeAcknowledgeTimeOut" value="500"/>
和强>
org.springframework.jms.listener.DefaultMessageListenerContainer.setReceiveTimeout(0);
或
org.springframework.jms.listener.DefaultMessageListenerContainer.setReceiveTimeout(10000);
org.springframework.jms.listener.DefaultMessageListenerContainer.setIdleTaskExecutionLimit(100);
public void setIdleTaskExecutionLimit(int idleTaskExecutionLimit)指定a的空闲执行限制 消费者任务,在其执行过程中没有收到任何消息。 如果达到此限制,任务将关闭并离开接收 到其他执行任务。默认值为1,关闭空闲资源 一旦任务没有收到消息就提前。这适用于动态 只安排;看&#34; maxConcurrentConsumers&#34;设置。最低 消费者的数量(见&#34;并发消费者&#34;)将被保留 直到任何情况下关闭。
在每个任务执行期间,进行多次消息接收尝试 (根据&#34; maxMessagesPerTask&#34;设置)将等待一个 传入消息(根据&#34; receiveTimeout&#34;设置)。我摔倒 那些在没有消息的特定任务返回中接收尝试的人, 对于接收的消息,该任务被认为是空闲的。这样的 任务仍可以重新安排;但是,一旦达到指定的 &#34; idleTaskExecutionLimit&#34;,它将关闭(如果是动态的话 缩放)。
如果您遇到过于频繁的放大和缩小,请提高此限制。 随着这个限制越来越高,闲置的消费者将被保留 更长的时间,一旦新的消息加载,就避免重新启动消费者 或者,指定一个更高的&#34; maxMessagesPerTask&#34;和/或 &#34; receiveTimeout&#34;价值,这也将导致闲置的消费者 保持较长时间(同时也增加了平均值) 每个计划任务的执行时间。)
http://activemq.apache.org/performance-tuning.html
优化确认在自动确认模式下使用消息时 (在创建消费者&#39;会话时设置),ActiveMQ可以确认 收到批量回邮件的消息(改进 性能)。 批量大小是预取限制的65% 消费者。此外,如果消息消耗很慢,则将发送批次 每300毫秒。您可以通过设置切换批量确认 ActiveMQ ConnectionFactory上的optimizeAcknowledge = true。
http://activemq.apache.org/what-is-the-prefetch-limit-for.html
一旦代理发送了预取限制数量的消息 消费者它不会向该消费者发送任何更多消息 直到消费者承认至少50%的预取 消息,例如prefetch / 2,它收到的消息。当经纪人有 收到上述确认后,它将发出进一步的预取/ 2 向消费者提供的消息数量,以及其自身的充值信息 预取缓冲区。请注意,可以指定预取限制 基于每个消费者(见下文)。