簡體   English   中英

Camel - 使用 spring-rabbitmq 進行確認管理

[英]Camel - Acknowledgement management with spring-rabbitmq

我正在嘗試為 rabbitMQ 隊列編寫一個簡單的消費者,在該隊列上配置了 DLX(綁定到另一個隊列)。 我目前正在使用駱駝 3.14.5。

我的駱駝路線聲明如下:

from("spring-rabbitmq:my-exchange?connectionFactory=#rabbitMQConnectionFactory&queues=my-queue")
            .onException(Exception.class)
                .log(LoggingLevel.ERROR, "Something went wrong!")
            .end()
            .process("myProcessor");

還有我的connectionFactory:

    <bean id="rabbitMQConnectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
    <property name="uri" value="amqps://myhost:5671"/>
    <property name="username" value="my-user"/>
    <property name="password" value="my-password"/>
    <property name="virtualHost" value="my-virtual-host"/>
</bean>

但是當我的處理器拋出異常時,我得到以下日志:

 16:33:10,441 ERROR [org.apache.camel.component.springrabbit.CamelDirectMessageListenerContainer] (pool-4-thread-5) Failed to invoke listener: org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Retry Policy Exhausted
    at org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer.recover(RejectAndDontRequeueRecoverer.java:76) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.config.StatelessRetryOperationsInterceptorFactoryBean.recover(StatelessRetryOperationsInterceptorFactoryBean.java:78) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:157) [spring-retry-1.3.3.jar:]
    at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:539) [spring-retry-1.3.3.jar:]
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:387) [spring-retry-1.3.3.jar:]
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:225) [spring-retry-1.3.3.jar:]
    at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:122) [spring-retry-1.3.3.jar:]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) [spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.amqp.rabbit.listener.$Proxy52.invokeListener(Unknown Source) [:2.4.6]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1577) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1568) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1512) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:1108) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:1068) [spring-rabbit-2.4.6.jar:2.4.6]
    at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149) [amqp-client-5.13.1.jar:5.13.1]
    at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:104) [amqp-client-5.13.1.jar:5.13.1]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_342]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_342]
    at java.lang.Thread.run(Thread.java:750) [rt.jar:1.8.0_342]
Caused by: org.springframework.amqp.AmqpRejectAndDontRequeueException
    ... 20 more
Caused by: org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1784) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1674) [spring-rabbit-2.4.6.jar:2.4.6]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1589) [spring-rabbit-2.4.6.jar:2.4.6]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_342]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_342]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_342]
    at java.lang.reflect.Method.invoke(Method.java:498) [rt.jar:1.8.0_342]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) [spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) [spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.3.22.jar:5.3.22]
    at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:97) [spring-retry-1.3.3.jar:]
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) [spring-retry-1.3.3.jar:]
    ... 15 more
Caused by: org.apache.camel.RuntimeCamelException: my processing exception

我應該如何將此消息配置為 nack 並發送到 rabbitMQ 代理上的 DLX 配置的隊列/連接工廠?

我不知道駱駝,但從 Spring 的角度來看,您可以使用DeadLetterPublishingRecoverer而不是RejectAndDontRequeueRecoverer 這會將失敗的消息重新發布到 DLQ,並在標頭中包含異常信息。

如果您只希望代理將原始消息移動到 DLQ,則必須使用死信交換和路由鍵配置隊列。

請參閱QueueBuilder

    /**
     * Set the dead-letter exchange to which to route expired or rejected messages.
     * @param dlx the dead-letter exchange.
     * @return the builder.
     * @since 2.2
     * @see #deadLetterRoutingKey(String)
     */
    public QueueBuilder deadLetterExchange(String dlx) {
        return withArgument("x-dead-letter-exchange", dlx);
    }

    /**
     * Set the routing key to use when routing expired or rejected messages to the
     * dead-letter exchange.
     * @param dlrk the dead-letter routing key.
     * @return the builder.
     * @since 2.2
     * @see #deadLetterExchange(String)
     */
    public QueueBuilder deadLetterRoutingKey(String dlrk) {
        return withArgument("x-dead-letter-routing-key", dlrk);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM