【问题标题】:Publisher Confirms gives ACK when message can not be routed by RabbitMQ当 RabbitMQ 无法路由消息时,Publisher Confirms 给出 ACK
【发布时间】:2020-10-02 06:29:50
【问题描述】:

我正在做一个小项目来检查 Publisher Confirms for RabbitMQ 与 Spring Cloud Stream 3.0.1 的工作原理。

当一个消息被发送到 RabbitMQ 的交换器时,我有一个特殊的情况,但是这个交换器不能路由这个消息。我预计此消息会被 Publisher 作为错误处理,但令我惊讶的是,它被作为 ACK 处理。

这是发布者的代码:

@Slf4j
@Timed
@Component
@RequiredArgsConstructor
public class TestPublisher {

    private final MessagingChannels messagingChannels;

    public boolean send(Message<Event<TestEvent>> message) {

        log.info("Message for Testing Publisher confirms sent: " + message);
        return messagingChannels.walletTest().send(message);
    }

    @ServiceActivator(inputChannel = TEST_ACK)
    public void acks(Message<?> ack) {
        log.info("Message ACK received for Test: " + ack);
    }

    @ServiceActivator(inputChannel = TEST_ERROR)
    public void errors(Message<?> error) {
        log.info("Message error for Test received: " + error);
    }
}

我可以在org.springframework.integration.handler.LoggingHandler的日志中看到这个消息

org.springframework.integration.amqp.support.ReturnedAmqpMessageException, failedMessage=GenericMessage [payload=byte[1009], headers={id=c9bc65bc-9256-1ce2-324f-167cc526a819, timestamp=1591962425292}] [amqpMessage=(Body:'{"payload":{"id":"f696668d-140e-4ba7-96c7-ea6decdfcccd","version":20000,"currency":"USD"},"eventName":"TEST_UPDATED",......contentType=application/json, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, deliveryTag=0]), replyCode=312, replyText=NO_ROUTE, .....]

如您所见,它被报告为带有replyCode=312 和replyText=NO_ROUTE 的失败消息。

但是,它是作为 ACK 而不是 NACK 接收的。我在文档中检查了一下,我认为这是启用 Publisher Confirms 的预期行为,但我想确认一下。如果是这种情况,是否有某种方法可以在 ACK 的上下文中检测到该消息无法路由?因为在这个上下文中,我没有replyCode 和replyText,我只有Publisher 发送的正确消息。

发布者确认已通过以下属性正确激活:

spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true

使用 errorChannelEnabled 和 confirmAckChannel 属性正确配置了 ACK 通道和错误。

【问题讨论】:

    标签: rabbitmq spring-integration spring-cloud-stream spring-rabbit


    【解决方案1】:

    就是这样工作的,在返回消息之后发送的是ack,而不是nack。

    the documentation

    对于不可路由的消息,一旦交换验证消息不会路由到任何队列(返回一个空的队列列表),代理将发出确认。如果消息也是强制发布的,basic.return 会在 basic.ack 之前发送给客户端。

    你无法判断它是在 ack 的上下文中返回的。

    如果您直接使用 Spring AMQP 而不是通过 Spring Cloud Stream,则可以,因为 ack 回调会获取 CorrelationData,其中将包含返回的消息。

    【讨论】:

    • 感谢您的回答。你证实了我的怀疑。
    猜你喜欢
    • 2021-01-10
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多