如果ThreadPoolTask​​Executor没有可用容量,则将消息保留在ActiveMQ队列中

时间:2013-06-12 10:05:24

标签: java spring activemq spring-integration

我有两个Java进程,第一个进程生成消息和put 它们到ActiveMQ队列上。第二个进程(使用者)使用Spring 集成以从队列中获取消息并在线程中处理它们。

我有两个要求:

  1. 消费者应该有3个处理线程。如果我有10条消息 通过队列进入,我希望有3个线程处理前3个 消息,其他7条消息应该缓冲。

  2. 当消费者在某些消息尚未处理时停止时,它就会消失 应该在重启后继续处理消息。

  3. 这是我的配置:

    <bean id="messageActiveMqQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg value="example.queue" />
    </bean>
    
    <int-jms:message-driven-channel-adapter
        destination="messageActiveMqQueue" channel="incomingMessageChannel" />
    
    <int:channel id="incomingMessageChannel">
        <int:dispatcher task-executor="incomingMessageChannelExecutor" />
    </int:channel>
    
    <bean id="incomingMessageChannelExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="daemon" value="false" />
        <property name="maxPoolSize" value="3" />
    </bean>
    
    <int:service-activator input-channel="incomingMessageChannel"
        ref="myMessageProcessor" method="processMessage" />
    

    第一个要求按预期工作。我产生10条消息和3条消息 myMessageProcessors开始处理每个消息。第1条消息一发出 完成后,处理第4条消息。

    但是,当我在处理所有消息之前杀死消费者时,那些消息 消息丢失了。重新启动后,消费者不会收到这些消息 试。

    我认为在上面的配置中是因为生成的线程 ThreadPoolTask​​Executor对消息进行排队。因此消息已被删除 来自incomingMessageChannel。因此我尝试设置队列容量 incomingMessageChannelExecutor:

    <property name="queueCapacity" value="0" />
    

    但是,当我收到3条以上的邮件时,我会收到错误消息:

    2013-06-12 11:47:52,670 WARN [org.springframework.jms.listener.DefaultMessageListenerContainer] - Execution of JMS message listener failed, and no ErrorHandler has been set.
    org.springframework.integration.MessageDeliveryException: failed to send Message to channel 'incomingMessageChannel'
    

    我也尝试将message-driven-channel-adapter更改为inbound-gateway, 但这给了我同样的错误。

    我是否必须在inbound-gateway中设置错误处理程序,以便错误返回到ActiveMQ队列?如果ThreadPoolTask​​Executor没有空闲线程,我如何配置队列以便消息保留在队列中?

    提前致谢,

    本尼迪克特

1 个答案:

答案 0 :(得分:2)

没有;您应该使用<message-driven-channel-adapter/>来控制并发性,而不是使用执行程序通道。

从频道中删除<dispatcher/>并在适配器上设置concurrent-consumers="3"