消息的可靠性
RabbitMQ 提供了一系列的特性和机制来确保消息的可靠性,即确保消息不丢失、按需到达目的地。要实现在 RabbitMQ 中消息的可靠性,可通过以下几个方面进行操作:
一、发送者的可靠性
1、生产者重试机制
什么是生产者重试机制?
消息队列(MQ)的生产者重试机制是指当生产者尝试将消息发送到消息队列中时,如果因为某些原因(如网络问题、队列不可用或其他任何导致消息发送失败的问题)导致消息未能成功发送,那么生产者会根据预设的策略尝试重新发送消息的过程。
如何实现生产者重试机制?
修改配置文件即可:
spring:
rabbitmq:
connection-timeout: 1s # 设置MQ的连接超时时间
template:
retry:
enabled: true # 开启超时重试机制
initial-interval: 1000ms # 失败后的初始等待时间
multiplier: 1 # 失败后下次的等待时长倍数,下次等待时长 = initial-interval * multiplier
max-attempts: 3 # 最大重试次数
2、生产者确认机制
什么是生产者确认机制?
生产者确认机制是一种确保消息从生产者安全达到消息队列的方法,尤其是在使用像RabbitMQ这样的消息中间件时,这种机制尤为重要。生产者确认(Publisher Confirms)也被视为是一种可靠性保障,使得生产者在发送消息后可以知晓该消息是否已被消息队列成功接收。
在不使用生产者确认机制的情况下,生产者将消息发送出去之后,就没有办法知道消息是否正确到达队列。这在某些场景下可能会导致数据丢失。因此,通过实现生产者确认机制,可以显著增加消息系统的可靠性。
如何实现生产者确认机制?
RabbitMQ提供的生产者消息确认机制包括Publisher Confirm
和Publisher Return
两种。在开启确认机制的情况下,当生产者发送消息给MQ后,MQ会根据消息处理的情况返回不同的回执。
-
当消息投递到MQ,但是路由失败时,通过Publisher Return返回异常信息,同时返回ack的确认信息,代表投递成功
-
临时消息投递到了MQ,并且入队成功,返回ACK,告知投递成功
-
持久消息投递到了MQ,并且入队完成持久化,返回ACK ,告知投递成功
-
其它情况都会返回NACK,告知投递失败
其中ack
和nack
属于Publisher Confirm机制,ack
是投递成功;nack
是投递失败。而return
则属于Publisher Return机制。
默认两种机制都是关闭状态,需要通过配置文件来开启:
spring:
rabbitmq:
publisher-confirm-type: correlated # 开启publisher confirm机制,并设置confirm类型
publisher-returns: true # 开启publisher return机制
这里publisher-confirm-type
有三种模式可选:
-
none
:关闭confirm机制 -
simple
:同步阻塞等待MQ的回执 -
correlated
:MQ异步回调返回回执
一般推荐使用correlated模式,兼顾了性能可靠性
ReturnCallback
ReturnCallback
是RabbitMQ中Java客户端库提供的一个接口,用于处理不能被路由到合适队列的消息。每个RabbitTemplate
只能配置一个ReturnCallback
,因此我们可以在配置类中统一设置:
package com.itheima.publisher.config;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Slf4j
@AllArgsConstructor
@Configuration
public class MqConfig {
private final RabbitTemplate rabbitTemplate;
@PostConstruct
public void init(){
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
@Override
public void returnedMessage(ReturnedMessage returned) {
log.error("触发return callback,");
log.debug("exchange: {}", returned.getExchange());
log.debug("routingKey: {}", returned.getRoutingKey());
log.debug("message: {}", returned.getMessage());
log.debug("replyCode: {}", returned.getReplyCode());
log.debug("replyText: {}", returned.getReplyText());
}
});
}
}
ConfirmCallback
ConfirmCallback
是RabbitMQ在Java客户端库中提供的一个接口,用于处理消息确认情况。当生产者将消息发送到RabbitMQ服务器时,可以通过实现ConfirmCallback
接口来监听这些消息是否成功被服务器接收(acknowledged)或被拒绝(nacked)。这是一种异步通信模式,允许生产者在不阻塞当前线程的情况下获得消息发送后的状态反馈。由于每个消息发送时的处理逻辑不一定相同,