• 售前

  • 售后

热门帖子
入门百科

架构师必备:系统性解决幂等问题

[复制链接]
落叶的时节 显示全部楼层 发表于 2022-1-15 06:34:25 |阅读模式 打印 上一主题 下一主题
Python微信订餐小程序课程视频

https://edu.caogenba.net/course/detail/36074
Python实战量化交易理财系统

https://edu.caogenba.net/course/detail/35475
要在应用中做到幂等,其实并不难,本文尝试做一个系统性的总结,欢迎一起探讨。
什么是幂等

某个操作执行一次,跟执行多次的效果一样。幂等一词来自于数学中的幂等,即f(f(x)) = f(x)。
需要保证幂等的场景

查询类的读操作,天然是幂等的,多次调用不会有副作用。需考虑以下几种写操作的情况:


  • 调用下游写接口
  • 写数据库、写Redis等
  • 消息订阅和处理
例子:不能给用户重复发放优惠券、现金奖励、通知等,商家更新商品时不能重复增加或减少库存。
下面分别讨论这几种情况。
1、调用下游写接口

主要依靠下游服务保证幂等。
本服务能做的是,在调下游写接口时不做重试,需设置重试次数为0。
2、自己服务保证

2.1 基于状态的幂等

这种情况比较简单,只有当满足前置条件时才允许操作,否则不允许更新(例如已经是终态),直接返回。
例子:订单支付成功后,不允许重复支付。
2.2 基于唯一键的幂等

幂等key的选取

与业务强相关,可以是商品id、订单id、用户id,或者日期等,或者是几个业务字段的组合。
几个例子:


  • 一个用户每天只能领一张优惠券,通过 用户id+优惠券类型+日期字符串 即可唯一标识
  • B端更新库存,商品id+该商品的版本号
  • C端扣库存,订单id
值得注意的是,需要区分新增和修改:修改时的幂等key往往需要带上版本号,才能区分是否同一次修改,每次修改对应一个唯一的版本号。
实现方式

MySQL表中为幂等key建立唯一索引:强幂等,例如资金、订单,绝对不允许重复处理,当插入重复数据时报错。
不推荐用Redis实现幂等,一旦Redis出问题,比如节点宕机,可能出现2个client同时获取到锁的情况。
MySQL幂等伪代码:
插入重复记录,捕获异常,提示幂等拦截。
  1. <code>    try {
  2.         // 插入记录
  3.         someDao.create(someRecord);
  4.     } catch (DataIntegrityViolationException e) {
  5.         // 如果是重复记录,返回异常
  6.         return failResponse("幂等拦截");
  7.     } catch (Throwable t) {
  8.         // 异常处理
  9.         return failResponse("其他异常");
  10.     }
复制代码
3、消息订阅和处理

MQ通常会保证消息至少发送一次(可能多次),并且在机器实例重启或发版时,consumer group会做rebalance,进而收到重复的消息。因此,消息的幂等处理必不可少。
实现方式:
在处理消息前加上Redis锁:如果上锁成功,则继续处理,否则稍后重试。


  • setnxex,不存在时才设置,时效即为锁的租期,否则忽略
  • 接下来的业务处理,如果是自身逻辑需要强幂等则使用上述数据库幂等方式,如果全部依赖下游则依赖下游实现幂等
Redis幂等伪代码:
  1. <code>    // 生成幂等key
  2.     String redisKey = buildRedisKey();
  3.     // 上Redis锁,租期为leaseTime
  4.     if (redisLock.tryLock(redisKey, leaseTime)) {
  5.         // 业务逻辑处理
  6.     } else {
  7.         // 稍后重试
  8.     }
  9.    
复制代码
来源:https://blog.caogenba.net/u012804784/article/details/122486392
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作