目标:
了解熟悉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] 再到 消费者的
两种模式过程:
只要利用这俩个callback就可以控制消息的 可靠性投递了
demo演示
确认模式:
1、在配置中开启 publisher-confirms 为 true
2、在rabbitTemplate定义 confirmCallBack 回调函数
](https://i-blog.csdnimg.cn/blog_migrate/1a8f5e588f32657980352e48a00269fd.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处理消息的模式:

@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

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

被折叠的 条评论
为什么被折叠?



