0


RabbitMQ 之 幂等性

RabbitMQ 之 幂等性

1. 概念

用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生副作用。
举个简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再相应客户端的时候也有可能出现网络中断或者异常等等。

2. 消息重复消费

消费者在消费 MQ 中的消息时,MQ 已把消息发送给消费者,消费者在给 MQ 返回 ack 时网络中断,故 MQ 未收到确认消息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但实际上该消费者已经成功消费了该条消息,造成消费者重复消费消息。

3. 解决思路

MQ 消费者的幂等性的解决一般使用全局 ID 或者写一个唯一标识,比如时间戳 或者 UUID 或者订单消费者消费 MQ 中的消息也可利用 MQ 的该 id 来判断,或者可按自己的规则生成一个全局唯一 id,每次消费消息时用该 id 先判断该消息是否已消费过。

4. 消费端的幂等性保障

在海量订单生成的业务高峰期,生产端有可能就会重复发送了消息,这时候消费端就要实现幂等性,这就意味着我们的消息永远不会被消费多次,即使我们收到了一样的消息。

业界主流的幂等性有两种操作:

  1. 唯一 ID + 指纹码机制,利用数据库主键去重;
  2. 利用 redis 的原子性去实现。

5. 唯一 ID + 指纹码机制

指纹码:我们的一些规则或者时间戳加别的服务给到的唯一信息码,它并不一定是我们系统生成的,基本都是由我们的业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id 是否存在数据库中,优势是实现简单,就一个拼接,然后查询判断是否重复;劣势就是在高并发是,如果是单个数据库就会有写入性能瓶颈,当然也可以采用分库分表提升性能,但也不是我们最推荐的方式。

6. Redis 原子性

利用 Redis 执行 setnx 命令,天然具有幂等性。从而实现不重复消费。


本文转载自: https://blog.csdn.net/weixin_42926863/article/details/126935135
版权归原作者 $驽马十驾$ 所有, 如有侵权,请联系我们删除。

“RabbitMQ 之 幂等性”的评论:

还没有评论