消息可靠性
- 消息生产可靠性
保证消息成功发送到RabbitMQ服务
- 消息消费可靠性
保证消息从服务中取出后正确消费掉
消息生产可靠性
- 记录消息发送
- 通过消息发送表记录每次发送MQ的数据和发送状态
- 消息发送和业务操作放在同一事务中
- 使用发送方确认模式更新消息表的状态
- 配置文件中通过如下设置,来开启消息发送确认机制
spring.rabbitmq.publisher-confirms: true
- 消息成功发送到交换机时,通过监听可以获取消息是否发送成功,在这里可以更新消息发送状态
// 发送消息时将业务Id一起发送,消息发送成功的回调会返回此信息
this.rabbitTemplate.convertAndSend("directExchange", "info-msg",
content, new CorrelationData("id"));
/**
* 消息发送到交换机监听类
* @author by peng
* @date in 2019-06-01 21:29
*/
@Slf4j
@Component
public class SendConfirmCallback implements RabbitTemplate.ConfirmCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init(){
rabbitTemplate.setConfirmCallback(this);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
log.info("Success... 消息成功发送到交换机! correlationData:{}", correlationData);
// 成功后更新消息发送表的发送状态
} else {
log.info("Fail... 消息发送到交换机失败! correlationData:{}", correlationData);
}
}
}
- 补偿机制
如果没有收到确认信息或者返回发送失败等,可以通过定时任务检查消息发送表,超时没发送成功的进行重发
消息消费的可靠性
- 开启手动ACK模式
配置文件中通过如下设置,来开启手动确认模式
#spring.rabbitmq.listener.direct.acknowledge-mode=manual
#spring.rabbitmq.listener.simple.acknowledge-mode=manual
业务处理成功后调用basicAck,rabbitMq服务接受到消息确认后,会认为此消息成功消费并从服务中删除此消息 业务处理失败后可通过basicNack或basicReject ,rabbitMq 会进行消息重发或将消息添加到死信队列
// 业务处理成功后调用,消息会被确认消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
// 业务处理失败后调用
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false, true);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
- 消息重试
消息消费失败后,可通过重新发送MQ消息
设置重试次数,避免永远消费不成功且一直重试的情况
- 消息幂等性
即避免消息被重复消费,可通过业务Id和业务表状态来判断消息是否消费过