骆驼与ActiveMQ的死信队列?

时间:2013-10-20 19:42:33

标签: jms activemq apache-camel dead-letter

我正在使用Dead Letter Channel EIP,正如Camel docs for Dead Letter Channel所描述的那样。这是我的camel.xml(删除了标题)

<camelContext id="camel"  xmlns="http://camel.apache.org/schema/spring">

            <!-- this is the Dead Letter Channel error handler, where we send failed message to a log endpoint -->




    <route  errorHandlerRef="myDeadLetterErrorHandler">

        <from uri="jms:q1" />
                    <doTry>
                            <validate><simple>${body[subsc]} regex '[a-z0-9]{8}' </simple> </validate>
                            <choice>
                                    <when>
                                            <simple>${body[key1]} regex '^(v1)$'</simple>
                                            <choice>
                                                <when>
                                                       <simple>${body[key2]} == 'v2'</simple>
                                                           <to uri="jms:getInfo" />
                                                 </when>
                                            </choice>        
                                    </when>
                                    <otherwise>
                                    <to uri="jms:invalid" />
                                    <stop />
                                    </otherwise>
                            </choice>
                    <doCatch>
                            <exception>org.apache.camel.ValidationException</exception>
                            <to uri="jms:invalid"/>
                    </doCatch>
                    </doTry>

    </route>

    <route>
        <from uri="jms:queue:deadlc" />
        <log message="Got ${body}" loggingLevel="ERROR" logName="cool" />
    </route>

</camelContext>

<!--
   Lets configure some Camel endpoints

   http://camel.apache.org/components.html
-->

<!-- configure the camel activemq component to use the current broker -->

<bean id="confact" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="vm://amq-broker?create=false"/>
        <property name="userName" value="${activemq.username}"/>
        <property name="password" value="${activemq.password}"/>
</bean>

<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" >
    <property name="connectionFactory" ref="confact" />

</bean>

<bean id="pooledConnectionFactory" 
      class="org.apache.activemq.pool.PooledConnectionFactory" 
      init-method="start" 
      destroy-method="stop">
    <property name="maxConnections" value="8" />
    <property name="connectionFactory" ref="confact" />
     <property name="expiryTimeout" value="-1" />  
    <property name="idleTimeout" value="-1" />
</bean>

<bean id="jmsConfig"  class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="pooledConnectionFactory"/>
    <property name="concurrentConsumers" value="8"/>
</bean>

<bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig"/>
</bean>


<bean id="myDeadLetterErrorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
        <property name="deadLetterUri" value="jms:queue:deadlc"/>
        <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/>
    </bean>

    <bean id="myRedeliveryPolicyConfig" class="org.apache.camel.processor.RedeliveryPolicy">
        <property name="maximumRedeliveries" value="3"/>
        <property name="redeliveryDelay" value="5000"/>
    </bean>

我只有一条路由有内容路由器,基本上说如果消息体有getInfo然后从jms:foo路由到jms:getInfo,如果消息体有performAction则从jms.foo路由到jms:performAction

我希望当jms:getInfo使用者没有运行时,传递会失败,重新传递尝试将按照spring XML中的规定进行。但没有任何反应,没有任何东西进入死信队列,而activemq会引发异常,如下所示。

有人可以解释为什么它不起作用吗?我的理解是,当消费者(它是将从基于内容的路由器接收消息的目的地)没有运行时,acivemq知道哪个甚至不应该传递它,并且应该立即抛出异常,然后由驼峰处理。已配置的死信通道。

我使用的是camel 2.10.3和activemq 5.8.0。

我怀疑activemq正在处理失败的邮件传递,而忽略了死信队列的camel xml配置,因为这些失败的邮件显示在activemq Web控制台的Activemq.DLQ中。如果使用者正在运行,则根据camel.xml中指定的路由成功传递消息。

  

0:58:46,317 |调试|使用以下消息将JMS消息发送到:queue:// getInfo:ActiveMQMapMessage {commandId = 0,responseRequired = false,messageId = null,originalDestination = null,originalTransactionId = null,producerId = null,destination = null,transactionId = null,expiration = 0 ,timestamp = 0,arrival = 0,brokerInTime = 0,brokerOutTime = 0,correlationId = a79a0f9e-c88f-4501-a56d-2d5667aa98e0,replyTo = temp-queue:// ID:myhost-57639-1382233787365-3:3:6 ,persistent = false,type = null,priority = 4,groupID = null,groupSequence = 0,targetConsumerId = null,compressed = false,userID = null,content = null,marshalledProperties = null,dataStructure = null,redeliveryCounter = 0,size = 0,properties = {breadcrumbId = ID:myhost-57439-1382232345453-1:1:1:1:6,CamelJmsDeliveryMode = 1},readOnlyProperties = false,readOnlyBody = false,droppable = false} ActiveMQMapMessage {theTable = {cluster = x78}} | org.apache.camel.component.jms.JmsConfiguration |骆驼(骆驼)线程#2 - JmsConsumer [bar]   20:58:48,044 |调试|驱逐非活动条目ID:8b0d77a3-afef-4612-a49f-22c1b81eb80e(20000毫秒后超时)| org.apache.camel.component.jms.reply.CorrelationTimeoutMap |骆驼(驼峰)线程#9 - JmsReplyManagerTimeoutChecker [getInfo]   20:58:48,044 |警告|在20000毫秒之后发生超时,等待具有correlationID [8b0d77a3-afef-4612-a49f-22c1b81eb80e]的回复消息。在ExchangeId上设置ExchangeTimedOutException(MessageId:ID:myhost-57439-1382232345453-1:1:1:1:5:ID-myhost-57640-1382233788284-0-2)并继续路由。 | org.apache.camel.component.jms.reply.TemporaryQueueReplyManager |骆驼(驼峰)线程#9 - JmsReplyManagerTimeoutChecker [getInfo]   20:58:48,045 |警告|执行JMS消息侦听器失败。引起:[org.apache.camel.RuntimeCamelException - org.apache.camel.ExchangeTimedOutException:未收到OUT消息:20000毫秒到期回复消息,其中relatedID:8b0d77a3-afef-4612-a49f-22c1b81eb80e未收到。交换[JmsMessage [JmsMessageID:ID:myhost-57439-1382232345453-1:1:1:1:5]]] | org.apache.camel.component.jms.EndpointMessageListener |骆驼(骆驼)线程#4 - JmsConsumer [bar]   org.apache.camel.RuntimeCamelException:org.apache.camel.ExchangeTimedOutException:未收到OUT消息:20000毫秒到期回复消息,其中未收到相关ID:8b0d77a3-afef-4612-a49f-22c1b81eb80e。交换[JmsMessage [JmsMessageID:ID:myhost-57439-1382232345453-1:1:1:1:5]]           at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1271)           at org.apache.camel.component.jms.EndpointMessageListener $ EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:187)           at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:108)           在org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:562)           在org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:500)           在org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468)           在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326)           at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264)           at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071)           at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063)           在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960)           at java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)           at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)           在java.lang.Thread.run(Thread.java:662)   引起:org.apache.camel.ExchangeTimedOutException:未收到OUT消息:20000毫秒到期回复消息,其中未收到相关ID:8b0d77a3-afef-4612-a49f-22c1b81eb80e。交换[JmsMessage [JmsMessageID:ID:myhost-57439-1382232345453-1:1:1:1:5]]           at org.apache.camel.component.jms.reply.ReplyManagerSupport.processReply(ReplyManagerSupport.java:133)           在org.apache.camel.component.jms.reply.TemporaryQueueReplyHandler.onTimeout(TemporaryQueueReplyHandler.java:61)           at org.apache.camel.component.jms.reply.CorrelationTimeoutMap.onEviction(CorrelationTimeoutMap.java:53)           在org.apache.camel.component.jms.reply.CorrelationTimeoutMap.onEviction(CorrelationTimeoutMap.java:30)           at org.apache.camel.support.DefaultTimeoutMap.purge(DefaultTimeoutMap.java:209)           at org.apache.camel.support.DefaultTimeoutMap.run(DefaultTimeoutMap.java:159)           at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:441)           at java.util.concurrent.FutureTask $ Sync.innerRunAndReset(FutureTask.java:317)           at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)           at java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 101(ScheduledThreadPoolExecu

1 个答案:

答案 0 :(得分:0)

您的JMS邮件有replyTo = temp-queue://ID:myhost-57639-1382233787365-3:3:6。 Camel希望收到回复消息,这就是你获得20000毫秒超时的原因。