RabbitMQ 消息确认机制、补偿机制、消息幂等性实践

本文介绍了如何确保RabbitMQ消息的可靠投递,包括生产者确认和消费者确认机制,以及如何处理消息重复消费的问题。在生产者端,通过启用发布者确认模式和设置回调处理未送达的消息。消费者端,通过手动确认模式确保消息正确处理。当消息丢失或重复消费时,提出了基于数据库和定时任务的补偿机制。同时,讨论了消息幂等性的重要性,并给出了利用全局唯一ID防止重复处理的方案。
摘要由CSDN通过智能技术生成

1. 场景

先看这么几个面试题:

  1. 如何保证消息的可靠性投递?即如何确定消息是否发送成功?
  2. 如果失败如何处理(补偿机制)?
  3. 如何保证消息不被重复消费?或者说,如何保证消息消费时的幂等性?

2. 消息的可靠性投递

消息确认

消息确认包括主要生产者发送确认消费者接收确认,因为发送消息的过程中我们是无法确认消息是否能路由等,一旦消息丢失我们就无法处理,所以需要确认消息,避免消息丢失。

2.1 生产者确认

我们知道生产者与消费者完全隔离的,不做任何配置的情况下,生产者是不知道消息是否真正到达 RabbitMQ,也就是说消息发布操作不返回任何消息给生产者。

那么怎么保证我们消息发布的可靠性投递?有以下几种常用机制。

image-20220223172851176

由于之前的文章对上面都有过介绍,所以这里不一一介绍,而一般采用的方式就是发布者确认模式(生产者确认模式)

原理:生产者将信道设置成 confirm 模式,一旦信道进入 confirm 模式,所有在该信道上面发布的消息都将会被指派一个唯一的 ID(从 1 开始),由这个 id 在生产者和 RabbitMQ 之间进行消息的确认。

这里的唯一 ID 能够唯一标识消息,在消息不可达的时候触发回调时可以获取该值,进行对应的错误处理,即对应的消息补偿机制。(记住这个唯一 ID,且是全局唯一,分布式系统中可采用雪花算法等方式)

confirm 模式最大的好处在于他可以是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者应用便可以通过回调方法来处理该确认消息,如果 RabbitMQ 因为自身内部错误导致消息丢失,就会发送一条 nack 消息,生产者应用程序同样可以在回调方法中处理该 nack 消息决定下一步的处理。

注:这里描述的场景都是能正确路由到队列中的,也就是不考虑失败通知(ReturnCallback)的情况。

由于现在大家开发基本都是通过 Spring Boot 的方式进行开发,所以,这里直接提供其基本配置类参考,如下:

/**
 * @description : 消息生产者
 */
@Component
@Slf4j
public class RabbitmqProducer {
   

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMessage(Map<String, Object> headers, Object message, String messageId, String exchangeName, String key) {
   
        // 自定义消息头
        MessageHeaders messageHeaders = new MessageHeaders(headers);
        // 创建消息
        Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders);
        /* 确认的回调 确认消息是否到达 Broker 服务器 其实就是是否到达交换器
         * 如果发送时候指定的交换器不存在 ack 就是 false 代表消息不可达
         */
        rabbitTemplate
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪了个王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值