RabbitMQ学习交换机之消息确认

发送者确认

发送者确认分两种
一是将消息发送到交换机时可能交换机不存在挂了,需要确认
二是交换机收到消息了,但在路由到队列时,找不到队列也需要确认
对应publisherConfirmpublisherReturns

publisherConfirm:

确认发送到交换机。需要在发送者设置publisherConfirm

spring:
  rabbitmq:
    addresses: localhost
    port: 5672
    username: guest
    password: guest
    publisher-confirm-type: correlated #发布确认(发布的交换机不存在)

一共有三种值,这里设置为correlated

public enum ConfirmType {
		/**
		 *在作用域操作中使用RabbitTemplate#waitForConfirms() (或waitForConfirmsOrDie()
		 */
		SIMPLE,
		/**
		 * 与CorrelationData一起使用将确认与发送的消息相关联
		 */
		CORRELATED,
		/**
		 * 发布者确认被禁用(默认)
		 */
		NONE
	}

RabbitTemplate的waitForConfirms() waitForConfirmsOrDie()

/*
等到自上次调用以来发布的所有消息都被代理确认或拒绝; 或直到超时。 如果超时到期,则抛出 TimeoutException。 在非确认通道上调用时,waitForConfirms 会抛出 IllegalStateException。
返回:
是否所有消息都被确认(并且没有消息被确认
*/
boolean waitForConfirms(long timeout) throws InterruptedException, TimeoutException;
/*
等到自上次调用以来发布的所有消息都被代理确认或拒绝; 或直到超时。 如果超时到期,则抛出 TimeoutException。 如果任何消息被拒绝,waitForConfirmsOrDie 将抛出一个 IOException。 当在非确认通道上调用时,它会抛出一个 IllegalStateException
*/
void waitForConfirmsOrDie(long timeout) throws IOException, InterruptedException, TimeoutException;

两种需要分别实现接口,然后添加到rabbitTemplate中,发布后会回调方法
默认消费者是自动确认的,一共三种确认方式

public class MyPubConfirm implements RabbitTemplate.ConfirmCallback{
    @Resource
    RabbitTemplate rabbitTemplate;
    @PostConstruct
    public void set(){
        rabbitTemplate.setConfirmCallback(this);
    }
    //发送消息到exchange(交换机不存在)
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, @Nullable String cause) {

    }
}

publisherReturns

需要开启publisherReturns和mandatory

spring:
  rabbitmq:
    addresses: localhost
    port: 5672
    username: guest
    password: guest
    publisher-confirm-type: correlated #发布确认(发布的交换机不存在)
    publisher-returns: true #从交换机发到队列,队列不存在会触发返回消息给生产者,需要开启mandatory,默认false不开启
    template:
      mandatory: true

继承RabbitTemplate.ReturnsCallback并添加到rabbitTemplate

public class MyPubConfirm implements RabbitTemplate.ReturnsCallback {
    @Resource
    RabbitTemplate rabbitTemplate;
    @PostConstruct
    public void set(){
        rabbitTemplate.setReturnsCallback(this);
    }
    //消息从exchange路由到队列(routingKey错误或队列不存在)
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {

    }
}

当从交换机路由到队列时会回调

消费者确认

public enum AcknowledgeMode {
    NONE,
    MANUAL,
    AUTO;
}

这里只说手动方式,将acknowledgeMode设置为manual

spring:
  rabbitmq:
    addresses: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        acknowledge-mode: manual

消费者代码:

	@RabbitListener(queues = "direct_queueA")
    public void consumer1(Message message, Channel channel) throws IOException {
        channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                false,
                true);
       // channel.basicAck(message.getMessageProperties().getDeliveryTag(),
                false);
       // channel.basicReject(message.getMessageProperties().getDeliveryTag(),
                false);
        System.out.println("consumer1----->"+new String(message.getBody()));

    }

消费者可以确认消息,拒绝消息
确认消息
basicAck(long deliveryTag, boolean multiple),
参数一是消息中的一个属性,类似于id;
参数二是否批量确认,比如消费者批量接受了多条消息(deliveryTag分别是1、2、3),那么在确认deliveryTag为3的消息时候就会把之前的1、2消息也会被确认
拒绝消息
basicNack(long deliveryTag, boolean multiple, boolean requeue)(批量)
basicReject(long deliveryTag, boolean requeue)
两个方法区别就是批量,basicReject只能一条一条拒绝,basicNack可通过设置multiple参数批量拒绝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值