csdn 这三年被分布式坑惨了,曝光十大坑
本篇主要内容如下:
一、分布式消息队列的坑
1. 消息队列的坑之非幂等
NOTE:
我是通过下面的内容明白了"idempotent幂等"的重要价值
(1)幂等性概念
所谓幂等性就是无论多少次操作和第一次的操作结果一样。如果消息被多次消费,很有可能造成数据的不一致。而如果消息不可避免地被消费多次,如果我们开发人员能通过技术手段保证数据的前后一致性,那也是可以接受的,这让我想起了 Java 并发编程中的 ABA 问题,如果出现了 ABA 问题,若能保证所有数据的前后一致性也能接受。
NOTE:
ABA problem和idempotent有什么相似之处?
(2)场景分析
(3)避坑指南
NOTE:
下面描述了多种实现idempotent的trick,其实归结为一句话就是:
"通过标志判断来过滤掉重复的消息,从而实现idempotent"
1、微信支付结果通知场景
NOTE:
这是典型的通过state machine来实现"idempotent幂等",从而轻松应付重复消息的问题,在Redis中,广泛应用这种trick
微信官方文档上提到微信支付通知结果可能会推送多次,需要开发者自行保证幂等性。第一次我们可以直接修改订单状态(如支付中 -> 支付成功),第二次就根据订单状态来判断,如果不是支付中,则不进行订单处理逻辑。
2、插入数据库场景
NOTE:
其中这种方式是经常会使用到的
每次插入数据时,先检查下数据库中是否有这条数据的主键 id,如果有,则进行更新操作。
3、写 Redis 场景
Redis 的 Set
操作天然幂等性,所以不用考虑 Redis 写数据的问题。
NOTE:
Redis
Set
是能够判断,是否存在的。
4、其他场景方案
- 生产者发送每条数据时,增加一个全局唯一 id,类似订单 id。每次消费时,先去 Redis 查下是否有这个 id,如果没有,则进行正常处理消息,且将 id 存到 Redis。如果查到有这个 id,说明之前消费过,则不要进行重复处理这条消息。
NOTE:
其实还是"通过标志判断来过滤掉重复的消息,从而实现idempotent"
- 不同业务场景,可能会有不同的幂等性方案,大家选择合适的即可,上面的几种方案只是提供常见的解决思路。