有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何知道消息是否已确认/取消?

我试图通过RabbitMQ和Spring Boot知道消息何时被接受(ack)或不接受(nack)

我想(通过exchange)将消息发送到队列中,并检查队列是否已接受消息。实际上,我想发送到两个不同的队列,但这并不重要,我假设如果对其中一个有效,那么对另一个也有效

因此,我使用CorrelationData尝试了类似的方法:

public boolean sendMessage(...) {
    CorrelationData cd = new CorrelationData();
    this.rabbitTemplate.convertAndSend(exchange, routingKey, message, cd);
    try {
        return cd.getFuture().get(3, TimeUnit.SECONDS).isAck();
    } catch (InterruptedException | ExecutionException | TimeoutException e ) {
        e.printStackTrace();
        return false;
    }
}

cd.getFuture().get(3, TimeUnit.SECONDS).isAck()应该得到falseis值,我想它还没有ack进入队列。但这总是正确的,即使routingKey不存在
因此,我假设这段代码正在检查消息是否已发送到exchange,并且exchange表示“是的,我收到了消息,它没有被路由,但我收到了”

因此,我在Rabbit/Spring文档中寻找了其他方法,但我没有找到方法

再解释一下,我想说的是:

在Spring引导代码中,我收到一条消息。必须将此消息发送到其他队列/exchange,但在其他两个队列确认ack之前,无法从当前队列中删除此消息(即已确认

我有手动确认,作为一个小伪代码,我有:

@RabbitListener(queues = {queue})
public void receiveMessageFromDirect(Message message, Channel channel,
                                     @Header(AmqpHeaders.DELIVERY_TAG) long tag){
    boolean sendQueue1 = sendMessage(...);
    boolean sendQueue2 = sendMessage(...);

    if(sendQueue1 && sendQueue2){
        //both messages has been readed; now I can ack this message
        channel.basicAck(tag, false);
    }else{ 
        //nacked; I can't remove the message util both queue ack the message
        channel.basicNack(tag,false,true);
    }

我已经测试了这个结构,即使队列不存在,值sendQueue1sendQueue2也始终为真


共 (1) 个答案

  1. # 1 楼答案

    确认是真实的;即使是无法破解的消息(我不完全确定原因)

    您需要启用返回的消息(并在future完成后检查CorrelationData中的返回消息是否为null-correlationData.getReturnedMessage())。如果不为null,则消息无法路由到任何队列

    只有当代理中存在bug,或者使用带有x-max-length和溢出行为reject-publish的队列时,才能获得nack