Spring DefaultMessageListenerContainer间歇性地使用消息

Spring DefaultMessageListenerContainer间歇性地使用消息,spring,jms,spring-jms,Spring,Jms,Spring Jms,我使用以下配置来使用队列中的消息。我需要确保任务执行器一次只能执行一个任务,因此我也按如下方式配置了任务执行器 <bean name="jmsTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="1" /> <property name="maxPo

我使用以下配置来使用队列中的消息。我需要确保任务执行器一次只能执行一个任务,因此我也按如下方式配置了任务执行器

<bean name="jmsTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="1" />
    <property name="maxPoolSize" value="2" />
</bean>

当我如上所述配置任务执行器时,一次会消耗10条消息(队列中有大量消息),容器会停止侦听消息近10-15分钟。我的容器配置如下:

<bean id="queueContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="destination" ref="queue" />
    <property name="maxConcurrentConsumers" value="1" />
    <property name="idleTaskExecutionLimit" value="1" />
    <property name="idleConsumerLimit" value="5" />
    <property name="receiveTimeout" value="10000" />
    <property name="recoveryInterval" value="10000" />
    <property name="taskExecutor" ref="jmsTaskExecutor" />
    <property name="messageListener" ref="queueListener" />
    <property name="autoStartup" value="true" />
</bean>
<bean name="jmsTaskExecutor"
            class="org.springframework.core.task.SyncTaskExecutor" />
public class QueueListener implements SessionAwareMessageListener<Message>{
 @override
 public void onMessage(Message msg,Session ses) throws JMSException{
 ....
 ....
 ....
 }
}

在做了一点谷歌搜索之后,我尝试使用SyncTaskExecutor而不是ThreadPoolTaskExecutor,我已将taskExecutor配置如下:

<bean id="queueContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="destination" ref="queue" />
    <property name="maxConcurrentConsumers" value="1" />
    <property name="idleTaskExecutionLimit" value="1" />
    <property name="idleConsumerLimit" value="5" />
    <property name="receiveTimeout" value="10000" />
    <property name="recoveryInterval" value="10000" />
    <property name="taskExecutor" ref="jmsTaskExecutor" />
    <property name="messageListener" ref="queueListener" />
    <property name="autoStartup" value="true" />
</bean>
<bean name="jmsTaskExecutor"
            class="org.springframework.core.task.SyncTaskExecutor" />
public class QueueListener implements SessionAwareMessageListener<Message>{
 @override
 public void onMessage(Message msg,Session ses) throws JMSException{
 ....
 ....
 ....
 }
}

但这会导致tomcat内存泄漏

您能告诉我如何在任务完成后才能实现消费消息和处理任务消息的行为吗

队列侦听器代码如下所示:

<bean id="queueContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="destination" ref="queue" />
    <property name="maxConcurrentConsumers" value="1" />
    <property name="idleTaskExecutionLimit" value="1" />
    <property name="idleConsumerLimit" value="5" />
    <property name="receiveTimeout" value="10000" />
    <property name="recoveryInterval" value="10000" />
    <property name="taskExecutor" ref="jmsTaskExecutor" />
    <property name="messageListener" ref="queueListener" />
    <property name="autoStartup" value="true" />
</bean>
<bean name="jmsTaskExecutor"
            class="org.springframework.core.task.SyncTaskExecutor" />
public class QueueListener implements SessionAwareMessageListener<Message>{
 @override
 public void onMessage(Message msg,Session ses) throws JMSException{
 ....
 ....
 ....
 }
}
公共类QueueListener实现SessionAwareMessageListener{
@凌驾
public void onMessage(Message msg,Session ses)引发JMSException{
....
....
....
}
}
当我如上所述配置任务执行器时,一次会消耗10条消息

这表明您的预取大小是10。 因此,即使只有一个线程处理消息,该线程一次也会接收10条消息。如果您以0或1的预取大小启动代理(取决于代理实现),您将获得所需的“一次一条消息”行为

例如,如果您使用的是ActiveMQ,则可以在设置预取大小时查看这一点


如果您的消息处理需要时间,那么我们需要查看更多的“onMessage”代码,以告知您可能在哪里花费时间。

您可以发布您的queueListener代码吗?是否也发布剩余的xml配置?您的预取大小是多少?我没有在任何地方明确设置预取大小,我已经发布了我的queueListener代码。你现在能查一下吗?