类似优惠券系统问题排查

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

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

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

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

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

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

超卖问题的话

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

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

所以很好解决 无非就是 用上乐观锁的思想 再发放的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来作为我们的锁

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

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

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

相关文章
|
6月前
|
SQL 运维 监控
如何排查线上问题的?
在当今的互联网时代,线上问题对企业的业务连续性和用户体验产生的影响越来越大。无论是网站崩溃、应用性能下降,还是服务中断,这些问题都可能对企业的声誉和用户满意度造成严重影响。因此,快速、准确地排查并解决线上问题变得至关重要。本文将介绍一些高效的线上问题排查方法,帮助您在面对线上问题时,迅速定位并解决问题。我们将在接下来的内容中详细讨论如何利用日志分析、监控系统、代码审查等手段,以及如何制定有效的应急预案。通过这些策略的实施,您将能够提高线上问题的解决速度,减少对业务的影响,并提高用户满意度。
156 2
|
小程序
优惠券流程
优惠券流程
313 0
|
存储 SQL 缓存
大厂的优惠券系统是如何设计的?
1 Scenario 场景 电商系统的促销手段(Electronic Commerce Systems): 优惠券 拼团 砍价 老带新
1214 0
|
数据挖掘 BI 开发者
异常流量渠道订单明细诊断|学习笔记
快速学习异常流量渠道订单明细诊断
110 0
异常流量渠道订单明细诊断|学习笔记
|
消息中间件 RocketMQ 开发者
下单异常问题演示|学习笔记
快速学习下单异常问题演示
108 0
下单异常问题演示|学习笔记
|
消息中间件 RocketMQ 开发者
下单问题分析及解决方式|学习笔记
快速学习下单问题分析及解决方式
167 0
下单问题分析及解决方式|学习笔记
|
运维 监控 NoSQL
一次线上问题排查所引发的思考
之前或多或少分享过一些内存模型、对象创建之类的内容,其实大部分人看完都是懵懵懂懂,也不知道这些的实际意义。
应用实时监控服务ARMS 5 月功能快报&优惠汇总
应用实时监控服务ARMS 5 月功能快报&优惠汇总来啦!
应用实时监控服务ARMS 5 月功能快报&优惠汇总
|
测试技术
实战 | JMeter 典型电商场景(下单/支付)的性能压测
实战 | JMeter 典型电商场景(下单/支付)的性能压测