一、秒杀实现思路秒杀其实就是一件商品,在某一个时间段内,由于降低了价格,超高的优惠,导致在这一个时间段内购买量大量增加,但是库存有限,产生的一种高并发现象。
秒杀最重要的就是减库存,增订单。同时需要判断用户是否多次秒杀,同时还要防止用户通过恶意软件刷单。
所以需要以下3点:
1、高可用:保证系统的高可用和正确性,设计PlanB备用。
2、一致性:保证秒杀减库存中的数据一致性。
3、高性能:涉及大量并发读写,所以需要支持高并发,从动静分离、热点发现与隔离、请求削峰与分层过滤、服务端极致优化来实现。
二、秒杀流程图
三、具体步骤的实现:
1、定时查询数据库中有哪些房间是特价房间,将特价房间信息(包含库存)存入redis(如果频繁操作数据库,会对数据库造成很大的压力,因此,将特价房间存入redis里减轻数据库的压力)
需要注意的是,特价房的真实库存应该用房间的总库存减去临时库存表中已经预定的数量
2、抢购
2.1判断用户是否登陆:
生成token
将生成的token存入redis
2.2、判断存入redis里的特价房是否还有库存
1.监测库存是否足够
2.是否是二次购买
3.执行购买
在高并发的情况下,很有可能存在买超的情况,如当第一个线程执行到第三步时还没有执行完,库存没有扣除,第二个线程就已经执行完了第二步,这样的话就会发生买超的情况,为了避免这种情况发生,可以加锁,如使用Java提供的synchronized,这样一来,这3个步骤就被“锁”住了,多个线程之间只能串行化执行。但是好景不长,整个系统的并发飙升,一台机器扛不住了。现在要增加一台机器
假设此时两个用户的请求同时到来,但是落在了不同的机器上,那么这两个请求是可以同时执行了,还是会出现库存超卖的问题。
为什么呢?
synchronized锁只对属于自己JVM里面的线程有效,对于其他JVM的线程是无效的。
这是因为两台机器加的锁不是同一个锁(两个锁在不同的JVM里面)。
那么,我们只要保证两台机器加的锁是同一个锁,问题不就解决了吗?
此时,就该