高并发秒杀系统

六种手段:

1.页面静态化

商品秒杀页面做静态化处理,常规请求不会到服务端。

2.cdn内容分发

将前端资源缓存到cdn上,就近分发给不同区域的客户端;

秒杀开始后将新的js文件同步到cdn上;

前端加一个控制器,控制同一用户短时间内的请求次数;

3.缓存

用多个缓存节点来抗住请求压力;

缓存击穿:事先做好缓存预热;加分布式锁,避免同一id的商品秒杀请求短时间内都进入到数据库内;

缓存穿透:加布隆过滤器过滤无效请求,但是要保证布隆过滤器的数据与缓存数据一致,只适合缓存读多写少的情形,可以把不存在的商品id也缓存起来;

4.mq异步队列

消息丢失问题:

通过消息发送表来记录消息发送情况,每隔一段时间通过job来重新发送消息。

消息重复问题:

通过维护消息处理表来规避重复消息。

消费延迟问题:

 延迟队列:延迟队列是一种特殊类型的队列,它允许消息在指定的时间点被消费。例如,用户下单后,系统可能需要等待一段时间来检查订单的支付状态,如果未支付则关闭订单。

5.限流

同一ip地址限流

同一用户限流

6.分布式锁

        分布式锁的过期时间:设置过期时间,即使在锁的持有者出现异常或者忘记释放锁的情况下,锁也会在到达预设的过期时间后自动释放,这样其他线程或进程就有机会获取到锁,继续执行任务。

        redis setnx命令加锁,但是加锁和设置过期时间不是原子的,可能会导致锁的过期时间设置失败,造成死锁等问题。

        redis set命令加锁可以保证原子性加锁和设置过期时间:使用SET命令将一个键值对写入Redis,其中键表示锁的名称,值表示锁的持有者(通常是线程或进程的唯一标识)。同时,设置一个过期时间,以防止锁一直被持有而无法释放。

SET lock_key lock_value NX PX expire_time

其中,lock_key是锁的名称,lock_value是锁的持有者(这里一般为request_id,保证在释放锁时不会释放错),NX表示只有当键不存在时才进行设置,PX表示设置键的过期时间,expire_time是过期时间(单位为毫秒)。

        

问题:

库存超卖:

数据库扣减库存:

        通过加锁来保证数据库读库存和更新库存的原子性,但是对性能有影响,可以用数据库乐观锁来提高性能:UPDATE product SET stock = stock - 2, version = version + 1 WHERE product_id = 1 AND version = 1;(乐观锁:在读取数据时并不加锁,而是在数据更新时检查在此期间是否有其他事务对数据进行了修改)。

缓存扣减库存:

        缓存库存,减少mysql压力,redis的incr方法是原子性的,可以通过该方法来扣减库存。(incr用来更新数据,只能保证原子写,想要保证原子读写,可以通过加锁的方式来实现,同样的性能会有损耗)

        通过lua脚本来修改库存,lua脚本本身保证原子性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值