RabbitMQ 实战之 保障信息的可靠性

552 阅读2分钟

消息可靠性

  • 消息生产可靠性

保证消息成功发送到RabbitMQ服务

  • 消息消费可靠性

保证消息从服务中取出后正确消费掉

消息生产可靠性

  1. 记录消息发送
  • 通过消息发送表记录每次发送MQ的数据和发送状态
  • 消息发送和业务操作放在同一事务中
  1. 使用发送方确认模式更新消息表的状态
  • 配置文件中通过如下设置,来开启消息发送确认机制

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和业务表状态来判断消息是否消费过