Loading

秒杀

流程

image

查询优惠券

判断券的库存

=》充足扣减 不足报错

image

image

超卖问题

image

只要在线程1扣减前查询,都会扣减

image

乐观锁性能比悲观锁性能好

版本号法

image

使用一个变量判断是否变化来判断 ==》利用库存代替版本

CAS

image

乐观锁弊端:成功率太低

==》对于库存问题:不用select相等,只要>0就行

==》对于必须相等的cas情况:分段锁,将100个库存分到10个表里面,到10个表里面分别去抢,成功率大幅度提高

image

一人一单

image

就是查询同个用户同张优惠券的订单是否存在

image

和库存超卖逻辑一样,大家都查询到为0

这里区别是判断数据是否存在,不是判断是否修改,只能用悲观锁

对整个流程抽象,对每个用户加锁

锁的释放时机

image

上面方法先获取事务再获取锁,锁释放后事务可能没有提交

image

先获取锁再提交事务,才能保证事务安全

事务是否生效

不懂springimage

所以说这样逻辑实际变成了判断能不能买,有没有买过,能买的话在执行扣库存和下订单的操作 ==》double check库存是否真的能够减少

集群下的线程没锁住

image

每个JVM都有自己的锁,导致每个锁都有一个线程获取

分布式锁

考虑JVM外部的锁监视器

image

多进程可见

互斥:难点,必须保证只有一个人获取到,其他人都失败

image

常用的分布式锁

image

Redis分布式锁流程

image

锁超时误删

image

在删除时要判断下==》在存入时要存一个线程标识

image

image

分布式锁的原子性问题

判断锁标识和释放不是一起执行,没有保证原子性,删掉的锁不是自己的

image

用setnx实现分布式锁的缺点

image

可重入锁

保存一个访问的次数

hash结构没有set nx

获取锁流程

image

image

锁重试和watch dog

image

主从一致性问题 - 联锁

image

主节点的锁没有同步到从节点上

解决方法就是不用主从,建立多个独立的锁

image

只有在每一个节点都拿到锁才能成功??

这样宕机了一台获取锁就不会成功

image

Redisson总结

image

image

Redis优化秒杀性能

image

将两个不用更改数据库的操作独立处理

image

在redis中执行判断和扣减,异步的执行下单和减库存的操作

image

image

基于Redis完成秒杀资格判断

image

List模拟消息队列

image

image

拿出消息后消息发送时丢失了

PubSub的消息队列

image

三种通配符

image

天生阻塞且可以多个消费者拿到消息

image

image

image

基于stream的消息队列-单消费模式

image

image

image

image

image

image

基于stream的消费队列-消费者组

image

image

image

注意改ID就是从pendinglist中读

image

用ACK确认

image

image

功能完善

消息队列对比

image

image

posted @ 2023-04-01 17:41  ydssx  阅读(50)  评论(0编辑  收藏  举报