Rabbit MQ 幂等性(处理消息重复消费问题的思路)

    科技2025-06-11  45

    Rabbit MQ 幂等性(处理消息重复消费问题的思路)

    1、什么是幂等性2、消费端的幂等性保障3、业界主流的幂等性操作3.1、唯一ID + 指纹码 机制3.2、利用 Redis 原子特性实现  

    1、什么是幂等性

      借助数据库的乐观锁机制举例:

    我们在执行一条更新库存操作的SQL语句时,在高并发的情况下,如何避免库存 count = 0了,还在减少的情况发生? 解决方案:加上版本号。 每次更新库存前,先根据主键查询 版本号 select count from t_rep where 主键 = **; 假设此时的版本号version = 1, 然后再根据版本号+主键作为条件去更新 update t_reps set count = count - 1,version = version +1 where version = 1 and 主键 = **. 这样当多个人查询到相同的版本号时,只有一个人能修改库存。

      总结什么是幂等性:

           可能你要对一件事进行一个操作,这个操作你可能要执行一百次或一千次,那么我们最终操作的结果,这一百次一千次的结果都是相同的。

     

    2、消费端的幂等性保障

      举例:在海量订单产生的业务高峰期,如何避免消息的重复消费问题?

           在高并发的情况下,可能会有很多消息到达MQ,然后我们的消费端要监听大量的消息。这个时候难免会遇到消息的重复投递,或者网络不稳定的原因导致闪断,进而导致 Broker 重发消息,这个时候不去做幂等,就会出现重复消费的问题。

    消费端实现幂等性,就意味着我们的消息永远不会消费多次,即使我们收到了多条一样的消息。

     

    3、业界主流的幂等性操作

     

    3.1、唯一ID + 指纹码 机制

     

    唯一ID + 指纹码 机制,利用数据库主键去重select count(1) from t_order where id = 唯一ID + 指纹码好处:实现简单坏处:高并发下有数据库写入的性能瓶颈。解决方案:跟进ID进行分库分表进行算法路由

           这里的指纹码可能是我们的一些业务规则,时间戳加上银行返回的唯一码,这个指纹码并不一定是我们系统生成的,而是一些外部的规则或者是我们内部的业务规则去拼接起来的。          指纹码的目的就是为了保障这次操作是绝对唯一的。

           具体的实现过程中,我们要保证 唯一ID + 指纹码在数据库中是唯一的 。在进行具体操作时,我们先通过 唯一ID + 指纹码 去数据库查询,如果没有数据我们就insert插入,如果有数据则证明已经被操作了,我们就不做任何操作。

     

    3.2、利用 Redis 原子特性实现

     

    使用 Redis 进行幂等,需要考虑的问题。  第一:我们是否要进行数据落库,如果落库的话,关键解决的问题是数据库和缓存如何做到原子性?  第二: 如果不进行落库,那么都存储到缓存中,如何设置定时同步的策略?

                        .

    Processed: 0.014, SQL: 8