2.1.2. 动脑学院 - 阿里双11秒杀模式管理与实现

秒杀只是一个特殊的购物流程。特点:

  1. 很多人抢(高并发)
  2. 不能超卖

如:浏览 -> 下单 -> 支付 -> 发货

2.1.2.1. 浏览

浏览量大:可增加缓存解决

2.1.2.2. 下单

2.1.2.2.1. 下单流程

  1. 修改库存
  2. 创建订单
  3. 支付状态:一般有时间限制,会弄一个定时任务,去检查关闭未付款订单

2.1.2.3. 支付

2.1.2.4. 发货

2.1.2. 秒杀模式

  1. 向上面那种,阿里的模式
  2. 浏览 -> 下单 -> 支付 -> 发货: 但是修改库存是在支付成功之后。(我自己感觉很不合理)

2.1.2. 修改库存

2.1.2.1. 利用数据库的乐观锁

并发量底,实现起来简单。

int i = update xxx set 库存 = 库存-购买量
where id = xxx and 库存 - 购买量 >= 0
判断i是否更新成功。

缺点: 并发量太低:300 or 700;mysql在HDD硬盘上300左右,SSD上面700左右

2.1.2.2. Memcached

long result = MemCachedClient.decr(key,value);
decr的特性:
原有值 > value = 正常
原有值 < value = 0
有线程安全保证,一旦失败则失败之前的值都没了

但是该API有一个坑,当原有值(100) < value(1000) 的时候,原有值会直接被变成0;

或许我猜测该api就是只要有值就直接减。那么后面如果有用户购买10个产品的时候,也购买不到了,所以不能直接符合需求

曲线救国解决方案:

注:该方法失败,视频中也翻车了。因为不能一步搞定。读取判断再写入就会存在并发脏数据。而又不能在代码中使用同步块和锁等手段。

针对该api的特性,另外增加一个变量来记录成功剪掉的库存数量。

MemCachedClient.set(key1,0); // 用来记录成功剪掉的库存
MemCachedClient.set(key,100); // 用来初始化库存
long result = MemCachedClient.decr(key,value);
if(result > 0){ // 如果成功,累加记录成功的数量
  MemCachedClient.incr(key1,value);
}else{ // 如果失败,把 (总的限制库存 - 成功的数量) set回去。
  MemCachedClient.set(key,total - MemCachedClient.get(key1));
}

2.1.2.3. redis

优点:事务 - 单进程,单线程

缺点:优点即是缺点。在大规模的并发写入效率不高

© All Rights Reserved            updated 2017-02-08 21:40:54

results matching ""

    No results matching ""