如何保证Rabbitmq不丢失消息的6大步【精通】
- 使用confirm来保障发送消息不丢
- 使用return来保障没有找到队列的消息不丢失
- 使用ack来保障消息的消费不丢失
- exchanger、queue、消息都要设置持久化
- 要搭建高可用的服务器集群,保障消息有备份
- 使用死信队列来处理丢弃的消息
在如何使用Confirm发送消息?
- 开启confirm
- publisher-confirms=“true”
<!-- 定义rabbitmq connectionFactory -->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"
publisher-confirms="true"
/>
- 监听并处理broker的回复消息
//2. 定义回调
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
/**
*
* @param correlationData 相关配置信息
* @param ack exchange交换机 是否成功收到了消息。true 成功,false代表失败
* @param cause 失败原因
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("confirm方法被执行了....");
if (ack) {
//接收成功
System.out.println("接收成功消息" + cause);
} else {
//接收失败
System.out.println("接收失败消息" + cause);
//做一些处理,让消息再次发送。
}
}
});
在如何使用Return接收没有队列的消息?
- 开启Return
- publisher-returns=“true”
<!-- 定义rabbitmq connectionFactory -->
<rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"
publisher-confirms="true"
publisher-returns="true"
/>
- 设置broker默认不丢弃消息,而是返回生产者
//设置交换机处理失败消息的模式
rabbitTemplate.setMandatory(true);
- 处理返回的这些消息
//2.设置ReturnCallBack
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
/**
*
* @param message 消息对象
* @param replyCode 错误码
* @param replyText 错误信息
* @param exchange 交换机
* @param routingKey 路由键
*/
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("return 执行了....");
System.out.println(message);
System.out.println(replyCode);
System.out.println(replyText);
System.out.println(exchange);
System.out.println(routingKey);
//处理
}
});
Rabbitmq的confirm与return的区别是什么?【熟悉】
- confirm是保障生产者与交换机之间的消息不丢失,return是保障交换机与队列之间的消息不丢失
- confirm使用
- 开启publisher-confirms=“true”
- setConfirmCallback
- return使用
- 开始publisher-returns=“true”
- setReturnCallback
- setMandatory(true),把丢弃的消息返回给生产者
如何使用ACK消费消息(手动确认模式)?【精通】
-
设置ACK的模式
- none:自动确认模式:消费者收到消息,就给broker发送确认收到的信息【默认】
- manual:手动确认模式:需要开发者使用api来回复broker的收到消息
- auto:依据是否有异常来自动确认模式,当有异常时不确认,无异常时自动给broker发送确认收到的消息
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="1" >
-
在代码中手动确认消息
- 确认成功
//3. 手动签收, // 参数一deliveryTag消息的唯一id, // 参数二:是否批量发送ack的信息给broker channel.basicAck(deliveryTag,true);
- 确认失败
/* // 参数一deliveryTag消息的唯一id, // 参数二:是否批量发送ack的信息给broker //第三个参数:requeue:重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端 */ channel.basicNack(deliveryTag,true,true);
如何使用限流?【精通】
-
配置
- 开启手动确认
- 配置每次从broker拉取多少条消息
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="1" >
如何使用TTL?【精通】
-
定义:设置消息在一定时间内,如果不消费,则自动删除
-
注意:
- 消息的过期时间只有在队列头才生效
- 队列上和消息都设置有过期时间,则以时间短的为标准
-
使用:
- 方式一:在队列上设置
- 在创建队列时设置x-message-ttl参数
- 方式二:在消息上设置
// 消息后处理对象,设置一些消息的参数信息 MessagePostProcessor messagePostProcessor = new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { //1.设置message的信息 message.getMessageProperties().setExpiration("5000");//消息的过期时间 //2.返回该消息 return message; } }; //消息单独过期 rabbitTemplate.convertAndSend("test_exchange_ttl", "ttl.hehe", "message ttl....",messagePostProcessor);
- 方式一:在队列上设置
什么是死信队列?【精通】
- 定义:
- 死信:在Rabbitmq中被丢弃的消息,既为死信
- 死信队列:是一个用于存储死信消息的普通队列
- 产生死信的3个方式
- 队列满
- TTL到期
- 拒收,不重回队列
- 设置死信队列的相关属性
- x-dead-letter-exchange
- x-dead-letter-routingkey
- x-max-length:设置队列的最大长度
什么是延迟队列?
- 定义:发送一个消息,消息在一定时间后才会被消费,而存放这些消息的队列既为延迟队列
- 实现:TTL+死信队列
Rabbitmq的消息追踪方式【了解】
-
Firehose:提供了消费者的开发成本
- 在消息队列中,自动增加一条跟踪消息(包括了消息经过了那些交换机、队列等下详细的信息)
- 使用:
- rabbitmqctl trace_on 开启
- rabbitmqctl trace_off 关闭
-
rabbitmq_tracing:降低rabbitmq的吞吐性能
-
把跟踪的消息日志,记录到对应的日志文件中
-
使用:
- 安装插件:
rabbitmq-plugins enable rabbitmq_tracing
- 在控制台配置那些队列需要记录跟踪日志
-
消息补偿机制方案【熟悉】
什么是幂等性?【精通】
- 定义:多次重复操作的结果和一次操作的结果一样,则称为幂等性
- 场景:
- 接口的幂等
- 消息的幂等
Rabbitmq的集群搭建【了解】
-
如何搭建高可用的集群
- 搭建多台服务器并组成集群
- 设置队列的镜像队列:队列的数据拷贝到多个节点上
-
客户端如何连接集群
- 安装HAProxy
- 在程序中使用HAproxy的访问地址及端口
什么是幂等性?【精通】
- 定义:多次重复操作的结果和一次操作的结果一样,则称为幂等性
- 场景:
- 接口的幂等
- 消息的幂等
Rabbitmq的集群搭建【了解】
-
如何搭建高可用的集群
- 搭建多台服务器并组成集群
- 设置队列的镜像队列:队列的数据拷贝到多个节点上
-
客户端如何连接集群
- 安装HAProxy
- 在程序中使用HAproxy的访问地址及端口