学习RabbitMQ高级特性

本文详细介绍了RabbitMQ的高级特性,包括消息可靠性(confirm确认模式、return退回模式)、ConsumerACK(自动确认与手动确认)、消费端限流(prefetch限制)以及TTL过期时间设置。通过示例代码展示了如何在SpringBoot中配置和使用这些特性,帮助读者深入理解RabbitMQ的消息处理机制。

目标:

了解熟悉RabbitMQ的高级特性


学习步骤:

高级特性主要分为以下几点, 官网介绍

1、消息可靠性投递 【confirm 确认模式、return 退回模式】
2、Consumer ACK 【acknowledge】
3、消费端限流 【prefetch】
4、TTL过期时间 【time to live】
5、死信队列 【Dead Letter Exchange】
6、延迟队列 【rabbitmq-delayed-message-exchange】
7、优先级队列 【x-max-priority】

在这里插入图片描述


前戏:项目搭建

1、创建两个module,一个为生产者,一个为消费者

分别添加如下依赖【或者将依赖放置在父工程下,两个module作为子工程引用即可】

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-amqp</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
     </dependency>
 </dependencies>

2、 配置RabbitMQ 的基本信息 [application.yml]

spring:
  rabbitmq:
    host: 服务器IP 
    port: 5672 # 端口默认为 5672
    username: guest # 默认账号有guest 密码一致
    password: guest
    virtual-host: /

3、编写配置类RabbitMQConfig,注册队列、交换机、以及绑定关系

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {
   
   
    public static final String QUEUE_NAME = "csnz_queue";
    public static final String EXCHANGE_NAME = "csnz_exchange";

    // 1、注册队列
    @Bean("CSNZQueue")
    public Queue getQueue(){
   
   
    	// 使用QueueBuilder构建一个队列,设置队列持久化,以及自动删除。
        return QueueBuilder.durable(QUEUE_NAME).autoDelete().build();
    }
    // 2、注册交换机
    @Bean("CSNZExchange")
    public Exchange getExchange(){
   
   
    	// 使用ExchangeBuilder构建一个交换机(类型可选,此处为通配符交换机),设置持久化和自动删除
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).autoDelete().durable(true).build();
    }
    // 3、绑定队列和交换机
    @Bean("CSNZBind")
    public Binding bindQueueExchange(@Qualifier("CSNZQueue")Queue queue,@Qualifier("CSNZExchange")Exchange exchange){
   
   
    	// 使用BindingBuilder 将刚刚声明的队列和交换机绑定并设置绑定的路由key
        return BindingBuilder.bind(queue).to(exchange).with("csnz.#").noargs();
    }
}

一、消息可靠性投递

RabbitMQ提供了两种模式来控制消息的投递(生产者发送的)可靠性

  • confirm 确认模式
  • return 退回模式
    在这里插入图片描述

因为消息投递过程是从 生产者Broker[exchange -> queue] 再到 消费者

两种模式过程:
  • 1:message从producer到exchange成功时会返回一个 confirmCallback
  • 2:message从exchange到queue失败时会返回一个 returnCallback

只要利用这俩个callback就可以控制消息的 可靠性投递了

demo演示

确认模式:

1、在配置中开启 publisher-confirms 为 true
2、在rabbitTemplate定义 confirmCallBack 回调函数

!](https://img-blog.csdnimg.cn/83be1b4662e8487c8c29cb69465d6650.png)

	/*
        确认模式:
        1、在配置中开启 publisher-confirms为true
        2、在rabbitTemplate定义confirmCallBack回调函数
     */
    @Test
    public void testConfirm(){
   
   
        // 定义confirmCallBack回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
   
   
            @Override
            /*
                CorrelationData:相关的配置信息【在convertAndSend重载方法中有包含此信息】
                ack;exchange交换机,是否成功收到了信息。
                cause:失败原因。如果成功接收则此值为null
             */
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
   
   
                if(ack){
   
   
                    System.out.println("消息成功发送");
                }else{
   
   
                    System.out.println("发送失败原因:" + cause);
                    // 重新发起或其他操作
                }

            }
        });

        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"csnz.testConfirm","测试确认回调模式");
    }

此时,如果发送消息时指定的交换机和路由键都是正确的,即代码块第27行参数正确,则第17行的 ack值为true,执行 消息成功发送到交换机后的逻辑代码
在这里插入图片描述
这里发送失败就是因为我们把交换机的名称写错了,换成正确的交换机名称就好
在这里插入图片描述

回退模式:

当消息发送给Exchange后,Exchange路由到queue失败时才会执行 ReturnCallBack

1、在配置中开启 publisher-returns 为 true
2、设置ReturnCallBack
3、设置Exchange处理消息的模式:
  • 如果消息没路由到queue
    • 1、丢弃消息(默认)即 rabbitTemplate.setMandatory(false);
    • 2、 返回给消息发送方 ReturnCallBack 即 rabbitTemplate.setMandatory(true);

在这里插入图片描述

	@Test
    public void testReturn(){
   
   
        // 设置交换机处理失败消息的模式
        rabbitTemplate.setMandatory(true);
        // 设置ReturnCallBack
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
   
   
            @Override
            /*
                Message:消息对象
                replyCode:错误码
                replyText:错误信息
                exchange:交换机
                routingKey:路由键
             */
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
   
   
                System.out.println(message);
            }
        });

        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"error.testReturn","测试回退模式");
    }

此时,如果发送消息时指定的交换机和路由键发生找不到的情况,即代码块第20行参数错误
情况一:没写第四行设置交换机处理失败消息的模式为true,则不会执行第15行的代码,因为消息失败默认是丢弃模式

在这里插入图片描述
在这里插入图片描述
因为默认此值就是false
在这里插入图片描述
情况二:设置交换机处理失败消息的模式为true,则会执行第15行的代码块,消息发送失败时,消息会通过回调返回,此时就可以查看消息发送失败的具体原因
在这里插入图片描述

二、Consumer Ack

Ack为Acknowledge,顾名思义,指的是消费者收到消息后的确认模式。

分为三种模式
  • 自动确认:acknowledge=“none”(默认)
    • 当消息一旦被consumer接收了,则自动确认收到,并移除消息缓存中的信息
  • 手动确认:acknowledge=“manual”
    • 手动ACK
    • 手动NACK
  • 根据异常情况判断是否确认:acknowledge=“auto”
实际业务情况:

一般不会使用 自动确认模式,因为收到消息后,很可能在进行业务处理时出现异常,造成数据丢失。真就啪一下没了。
一般都是使用 手动确认模式

  • 即在业务处理成功后,调用 channel.basicAck() 进行手动确认,会发送给 broker 一个应答,代表消息处理成功
  • 如果在进行业务处理时发生异常,则调用 channel.basicNack() 方法【如果设置了重回队列,broker 就会将没有成功处理的消息重新发送。否则将该消息从队列中剔除】。

demo演示

自动确认模式:

1、定义一个监听器:AckListener 实现 MessageListener 接口
2、在onMessage方法上绑定要监听的队列
@Component
public class AckListener implements MessageListener {
   
    
    @Override
    @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
    public void onMessage(Message message) throws Exception 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值