类似优惠券系统问题排查

简介: 问题排查与解决方案

总结就是 所有敏感的操作 类似跟钱挂钩的 比如发放优惠券的前提就是判断到发放 我们一般都是让一系列操作是原子性 并且别人获取不到这个锁

如果数据不敏感 类似点赞的 那么没有必要 因为一致性必须牺牲高可用的

工厂模式帮我们自动根据传入参数自动执行不同的函数

策略模式帮我们设定了不同的方案 根据传入的参数选择不同的参数去选择不同的方法

首先大体确定问题范围属于并发引起的问题 所以很容易就想到锁了

超卖问题的话

我们只需要确定为什么会超卖

无非就是再发放优惠券的时候没有确定是否已达用户领取上限 或者是 优惠券总发放上限

所以很好解决 无非就是 用上乐观锁的思想 再发放的sql语句加上where条件判断而已

锁失效问题

查询 判断 新增满足这三步之后才会发放优惠券

逻辑上确实没问题 但是我们考虑的只是单机

如果我们并发前提下 A线程执行新增之前 B执行到判断了

这个时候就会出现 同时满足的情况

所以实际上也就是 查询判断新增这三步核心逻辑 我们分开写了 没有使他们同时执行 不具备原子性,

所以我们直接考虑用 Synchronized实现

锁方法太大了 太慢了 所以我们考虑锁方法块 锁的对象由于我们知道Long存在常量池复用-127到128的对象

所以不能直接锁long 要锁实际值 所以使用apiuserId.toString().intern()来最终解决这个问题

事务边界问题

如果我们开启事务之后 才获取锁 然后释放锁 再提交事务

这个时候就会出现释放锁之后 还没提交事务 其他线程拿到锁 访问了资源 也就是脏读问题

那么只需要换个思考方式 那么我就提交好了再释放锁 不就可以了嘛

所以很简单 就是先获取锁 开启事务 提交事务 释放锁

事务失效问题

那么都用到事务了 事务肯定就会存在失效的情况

排查

1.事务方法非public修饰 spring会有方法判断方法如果不是public进不去

2.非事务方法调用事务方法 因为事务底层是aop生成动态代理 我们当前类调用实际上是this去调用 这个类似成员变量赋值都是this.set get

那么我们非事务 自然aop不会帮我们生成动态代理对象 所以也就不会检测到事务了 所以也就失效了 解决方案就是 手动调用aop对象去调用方法 也就是 aop(动态代理对象).方法名

3.事务方法的异常被捕获 被捕捉了 自然没异常就不会回滚

4事务异常类型不对 类型不对 也就不会检测到 也就相当于没回滚了

5事务传播行为不对 事务之间是有隔离性的 那么A回滚了 是不会影响B的 因为B是独立于A的 当然如果这里是嵌套事务的话 那么就大的会影响小的 小的不会影响大的

6.没有被Spring管理 如果类都没被spring管理 aop都没办法帮你创建代理对象 那就肯定失效了

集群锁失效问题

我们使用的Synchronized底层是基于jvm的锁监视器去做的

当我们部署了多个实例 那么就会有多个jvm

所以自然每个jvm的锁监视器就不一样了 那么这个时候实际上 就会有多个user2的锁

解决方案 类似seata记录表 不再基于jvm的锁监视器 而是基于数据库表 也就是设置分布式锁

分布式锁问题

我们一开始是加锁后再设置过期时间 那么如果加锁后宕机了呢 对吧 实际上还是回到两个操作是分开的 解决方案就是让两个操作有原子性 一起执行

加锁同时设置过期时间指令:SET key value NX EX seconds

那么设置了过期时间后 就会出现当线程1阻塞的时候 锁A过期了

所以这个时候别的线程2就可以获取到锁A 这个时候 开始执行业务

但是这个时候线程1醒过来了 继续删除释放锁 就会导致线程3可以拿到锁了 就会出现又并发了

解决方案 我们设置线程名字为锁key 比如 key为 Thread1 加上userid 这种唯一标识

删除之前判断是否当前线程的 如果不是就不删

记得把判断跟删除 作为一个操作 不然又会出现极端情况了

后面我们还使用了redisson来作为我们的锁

因为他支持重入,看门狗等 而且使用更加简单

还引入了工厂模式来帮我们自然化 根据用户传入的锁类型支持不同的获取锁的对象

后面引入策略模式来帮我们解决多种获取失败方案 解决代码冗余问题

相关文章
|
10月前
|
小程序
优惠券流程
优惠券流程
241 0
|
11月前
|
存储 SQL 缓存
大厂的优惠券系统是如何设计的?
1 Scenario 场景 电商系统的促销手段(Electronic Commerce Systems): 优惠券 拼团 砍价 老带新
885 0
|
运维 PHP Perl
总结一些线上问题排查的命令,可能用得到!
开发运维,统计所遇到的运维问提。运维问提排查,以下场景,你可能遇到?
126 0
总结一些线上问题排查的命令,可能用得到!
|
存储 NoSQL 测试技术
记一次业务系统登录报错404问题排查与解决实践
业务系统登录报错404问题排查与解决实践过程记录总结
记一次业务系统登录报错404问题排查与解决实践
|
API
云市场资源包额度预警设置及使用明细查询操作指导
阿里云云市场是软件交易及交付平台。云市场致力于为中小型企业提供全方面的 IT 服务,大幅降低企业互联网化成本, 打造企业上云、产品选购、服务落地、交易一体化流程。共同构建云上生态,让信息化更简单。作为阿里云的战略发展点,承接着中国云生态各个链条产品的落地。云市场平台提供完备的服务监管来保障用户利益,并把更多的产品、品牌及销售资源赋能商家。客户在购买使用云市场服务后为了避免当资源包耗尽时,面临服务不可用风险。通常有设置资源包额度预警和查看使用明细得需求。但是由于云市场控制台的不熟悉,往往不知如果进行额度预警的调整及设置。本文简单介绍设置资源包额度预警和查看资源包用量明细操作步骤,以供参考
475 0
云市场资源包额度预警设置及使用明细查询操作指导
|
消息中间件 RocketMQ 开发者
下单异常问题演示|学习笔记
快速学习下单异常问题演示
73 0
下单异常问题演示|学习笔记
|
消息中间件 RocketMQ 开发者
下单基本流程小结|学习笔记
快速学习下单基本流程小结
94 0
|
数据挖掘 BI 开发者
异常流量渠道订单明细诊断|学习笔记
快速学习异常流量渠道订单明细诊断
61 0
异常流量渠道订单明细诊断|学习笔记
阿里云资源包额度预警设置操作指导
资源包为预付费的抵扣包,是指您根据业务量级预估一次性付费购买相应规格的商品资源包。自购买日起,一年内有效,有效期内产生的计费调用量优先使用资源包抵扣额度,超出有效期未抵扣的资源包额度自动失效。资源包过期或额度耗尽时,服务将会自动切换为后付费进行按量计费。为了避免当资源包耗尽时,面临服务不可用风险。设置资源包额度预警后,则当资源包剩余一定额度时,会通过短信、邮箱方式向您推送通知。阿里云虽然提供了资源包额度预警设置,但是由于对阿里云控制台的不熟悉,往往不知如果进行额度预警的调整及设置。本文简单介绍设置资源包额度预警操作步骤,以供参考。
775 0
阿里云资源包额度预警设置操作指导
|
云安全 弹性计算 小程序
阿里云赊呗开通、额度及还款常见问题解答FAQ
赊呗是蚂蚁集团旗下商诚融资担保有限公司为买卖双方在赊购交易中提供的担保服务。您在阿里云采购云产品时,可以使用赊呗额度先行支付,无需立即支付现金,享受先采购后付款的上云体验。
759 0
阿里云赊呗开通、额度及还款常见问题解答FAQ