繁体   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