RabbitMQ的高级特性【一】

RabbitMQ的高级特性

1.消息的可靠传递

RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。

  • confirm 确认模式
  • return 退回模式

rabbitmq 整个消息投递的路径为:

producer—>rabbitmq broker—>exchange—>queue—>consumer

  • 消息从 producer 到 exchange 则会返回一个 confirmCallback 。
  • 消息从 exchange–>queue 投递失败则会返回一个 returnCallback 。

我们将利用这两个 callback 控制消息的可靠性投递.

1.1确认模式

  1. 确认模式开启:配置文件中开启publisher-confirms为"true"
spring:
  rabbitmq:
    host: 127.0.0.1
    port: 49154
    virtual-host: /
    username: guest
    password: guest
    publisher-confirms: true #开启确认模式
mq:
  exchange_name: "springboot_item_topic_exchange"
  queue_name: "springboot_item_queue"
  1. 在rabbitTemplate定义ConfirmCallBack回调函数
 public void testConfirms(){
        //2.定义回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData 相关的配置信息
             * @param b exchange交换机 是否成功收到了消息。true 成功,false代表失败
             * @param s 接收的信息
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if(b){
                    System.out.println("接收成功"+s);
                }else{
                    System.out.println("接收失败"+s);
                    //TODO 
                    //做一些处理,让消息重新发送
                }
            }
        });
        //3.发送消息
        rabbitTemplate.convertAndSend("springboot_item_topic_exchange","item.insert","插入");
    }

1.2退回模式

回退模式: 当消息发送给Exchange后,Exchange路由到Queue失败是 才会执行 ReturnCallBack

1.开启回退模式:配置文件中publisher-returns设为"true"

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 49154
    virtual-host: /
    username: guest
    password: guest
    publisher-confirms: true #开启确认模式
    publisher-returns: true #开启回退模式
mq:
  exchange_name: "springboot_item_topic_exchange"
  queue_name: "springboot_item_queue"

2.设置ReturnCallBack

public void testReturn(){
        //设置交换机处理失败消息模式
        rabbitTemplate.setMandatory(true);
        //2.设置ReturnCallBack
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             *
             * @param message 消息对象
             * @param i 错误码
             * @param s 错误信息
             * @param s1 交换机
             * @param s2 路由键
             */
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("消息:"+message);
                System.out.println("错误码:"+i);
                System.out.println("错误信息:"+s);
                System.out.println("交换机:"+s1);
                System.out.println("路由键:"+ s2);
                 //TODO 
            }
        });
        //3.发送消息
        rabbitTemplate.convertAndSend("springboot_item_topic_exchange","item.insert","插入");
    }

2.Consumer Ack

ack指Acknowledge确认。 表示消费端收到消息后的确认方式。

有三种确认方式:

  • 自动确认:acknowledge=“none”
  • 手动确认:acknowledge=“manual”
  • 根据异常情况确认:acknowledge=“auto”

其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从RabbitMQ 的消息缓存中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。

Consumer ACK机制:

  1. 设置手动签收。acknowledge=“manual”

  2. 让监听器类实现ChannelAwareMessageListener接口

  3. 如果消息成功处理,则调用channel的 basicAck()签收

  4. 如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给consumer

配置文件:

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 49154
    virtual-host: /
    username: guest
    password: guest
    listener:
      direct:
        acknowledge-mode: manual
mq:
  exchange_name: "springboot_item_topic_exchange"
  queue_name: "springboot_item_queue"
@Component
public class AckListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            //1.接收消息
            System.out.println(new String(message.getBody()));
            //2.业务处理逻辑
            //TODO
            //假如出现异常
            int i=4/0;
            //3.手动签收
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            //4.拒绝签收
            //第三个参数requeue,重回队列,true为重新回到queue中,broker重新发送给消费端
            channel.basicNack(deliveryTag,true,true);
            //channel.basicReject(deliveryTag,true)
        }
    }
    @Override
    public void onMessage(Message message) {
        ChannelAwareMessageListener.super.onMessage(message);
    }
}

3.消费端限流

Consumer 限流机制:

  1. 确保ack机制为手动确认。

  2. listener-container配置属性

perfetch = 1,表示消费端每次从mq拉去一条消息来消费,直到手动确认消费完毕后,才会继续 拉去下一条消息。

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 49154
    virtual-host: /
    username: guest
    password: guest
    publisher-confirms: true #开启确认模式
    publisher-returns: true #开启回退模式
    listener:
      direct:
        acknowledge-mode: manual #手动应答
        prefetch: 1 #限制流,每次发送一条数据。
mq:
  exchange_name: "springboot_item_topic_exchange"
  queue_name: "springboot_item_queue"
@Component
public class QosListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        //1.获取消息
        System.out.println(new String(message.getBody()));
        //2.处理业务逻辑
        
        //3.签收
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
    }

    @Override
    public void onMessage(Message message) {
        ChannelAwareMessageListener.super.onMessage(message);
    }
}

4.TTL

Time To Live,消息过期时间设置

4.1 队列统一过期

生产端对队列的声明:

    /**
     *  声明队列
     *  过期时间 100000
     */
    @Bean("itemTopicQueue")
    public Queue topicQueue(){
        return QueueBuilder.durable(queue_name).withArgument("x-message-ttl",100000).build();
    }

4.2消息单独过期

 @Test
    public void testTimeOut(){
       //消息处理对象,设置消息参数信息
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //设置过期时间
                message.getMessageProperties().setExpiration("100000");
                return message;
            }
        };
        //发送消息
        rabbitTemplate.convertAndSend("springboot_item_topic_exchange","item.insert","插入",messagePostProcessor);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值