当前位置:首页 » 《随便一记》 » 正文

因为锁的问题,我们被扣了1万

22 人参与  2023年02月17日 08:57  分类 : 《随便一记》  评论

点击全文阅读


前言

春节放假期间,一个项目上的积分接口被刷,而且不止一个人在刷,并且东西也被兑走,放假晚上被人叫起来排查问题,通过这个人的积分明细观察,基本一秒就能获取一次,远远超过了积分规则限定的次数,这肯定是用脚本了,虽然后期联系死活说自己是正常途径获取。由于是业主,我们还是决定自己来承担这个损失,被项目方从合同中扣除奖品费用1万余元。

问题原因

先说下接口的逻辑层次结构:

–controller 积分获取接口,用PointController表示

–service 积分获取接口service,用PointService表示

我用伪代码来表示整个调用逻辑:

PointController

@RestControllerpublic class PointController {@Resourceprivate PointService pointService;@GetMapping(/addPoint)public Response addPoint() {//分布式锁,使用redis的NX命令RedisDistributedLock lock = new RedisDistributedLock();    //创建一个3s过期,100ms休眠的锁if(lock.lock("POINT_KEY", 3000L, 100L)) {try {        //调用pointService.addPoint();} catch (Exception ex) {e.printStackTrace;} finally {        //解锁lock.unlock("POINT_KEY");}}return Response.ok(getLastPoint());}}
创建一个分布式锁对象,该分布式锁使用redis的NX命令实现随后创建一个3s过期的分布式锁,以便锁住该新增积分的请求最后在新增积分执行完后,在finally中释放锁最后返回该用户的最终积分

PointService

public class PointService {    @Transactional(rollbackFor = Exception.class)  public void addPoint() {    //查询积分规则    PointRule pointRule = getPointRule();    //查询用户该积分项的积分获取记录总数    Integer total = getPointRecords();    //判断该用户的积分记录总数是否大于 积分规则限定的次数    //大于则不处理,返回    if(total - pointRule.getRuleTimes >= 0) {      return;    }        //生成积分记录    int insert = insertPointRecords();    //更新用户总积分    if(insert > 0) {      updateUserPoint();    }  }}

PointService 中的添加积分逻辑:

首先查询该项目积分规则,查询用户该积分项的积分获取记录总数判断该用户的积分记录总数是否大于 积分规则限定的次数,大于则不处理,返回生成积分记录更新用户总积分

该添加积分的逻辑整体上看好像没什么问题,也确实在一切正常的情况下运行是不会有问题的。

如果PointService 中的添加积分逻辑在分布式锁有效期3s内执行完,是不会有问题的。

但如果PointService中的添加积分逻辑超过3s…那是不是后续请求又可以获取锁了,这也正是这次事故的原因。

因为PointService中的添加积分逻辑超过了3s,并且上一个请求的事务还未提交,后续请求已经获取锁进入PointService,在查询积分记录后,判断还是满足规则,继续执行后续的逻辑,造成用户能够获取多次积分。

问题处理

原因总结一下:

添加积分逻辑处理时间过长分布式锁超时

第一个问题:逻辑改动过大,需要时间调整,没有采用

第二个问题:换成Redisson,因为redisson在即使超时的情况下也会续锁,避免锁超时

总结

一方面因为忙于做项目,忽略了代码Review,另一方面测试的时候没有对接口进行并发测试,或者根本没有测出来,第三没有监控工具监控长事务,以及频繁请求。

作者其他文章:
《Prometheus+Grafana 实践派》专栏火热更新中

Grafana 的介绍和安装Grafana监控大屏配置参数介绍(一)Grafana监控大屏配置参数介绍(二)Grafana监控大屏可视化图表Grafana 查询数据和转换数据Grafana 告警模块介绍Grafana 告警接入飞书通知

Spring Boot Admin 系列

Spring Boot Admin 参考指南SpringBoot Admin服务离线、不显示健康信息的问题Spring Boot Admin2 @EnableAdminServer的加载Spring Boot Admin2 AdminServerAutoConfiguration详解Spring Boot Admin2 实例状态监控详解Spring Boot Admin2 自定义JVM监控通知Spring Boot Admin2 自定义异常监控Spring Boot Admin 监控指标接入Grafana可视化

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/53304.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • (番外)+(全书)爱若有天意,兜转终可回全书+后续+结局(宋清澜萧沉)_爱若有天意,兜转终可回全书+后续+结局列表_笔趣阁(爱若有天意,兜转终可回全书+后续+结局)
  • [繁花盛意难平]小说节选推荐_陆依霜轩辕翊陆青仪节选推荐
  • [纵她追悔,爱已成荒芜]小说精彩节选推荐_「苏萌林澈白月光」小说精彩节选试读
  • [老婆让我别拦着她嫁豪门]小说节选免费试读_[屈英哲韩海雪温文尔雅]精彩章节分享
  • 青梅诱人竹马男主轻点宠(许嘉易顾思瑜)全书浏览_青梅诱人竹马男主轻点宠全书浏览
  • 阮雾梨闻砚辞人面桃花长相忆结局+番外(阮雾梨闻砚辞)_人面桃花长相忆结局+番外阮雾梨闻砚辞列表_笔趣阁(阮雾梨闻砚辞)
  • 人面桃花长相忆闻砚辞结局+番外+续集(阮雾梨闻砚辞)结局_(阮雾梨闻砚辞人面桃花长相忆闻砚辞结局+番外+续集全书结局)结局(阮雾梨闻砚辞)
  • 日暮青山绿渐隐老书虫(许星森纪冰雪)全书浏览_日暮青山绿渐隐老书虫全书浏览
  • 被网暴包女大后,施暴者倾家荡产全文在线阅读_[鹿晓南妹妹张脸]小说节选推荐
  • 日暮青山绿渐隐+全书+番外(许星森纪冰雪)列表_日暮青山绿渐隐+全书+番外(许星森纪冰雪)结局篇+番外在线
  • 梧桐叶落尽,再回来爱你番外+(霍云琛林思雨)列表_梧桐叶落尽,再回来爱你番外+(霍云琛林思雨)梧桐叶落尽,再回来爱你番外+在线
  • 爱恨缠绵,花心愁欲断,顾墨琛虞梵音_爱恨缠绵,花心愁欲断,顾墨琛虞梵音

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1