秒杀---使用乐观锁实现或cache实现
程序员文章站
2022-05-04 16:41:19
...
概念
秒杀系统的特点
- 新品上市 价格低廉
- 市场造势 大幅推广
- 指定时间开售
- 瞬时售空
- 读多写少
秒杀系统难点
- 高并发、负载压力大
- 竞争资源是有限的
- 对其他业务的影响
- 提防“黄牛党”
秒杀系统应用场景
- 商品抢购
- 群红包
- 优惠卷领取
- 抢火车票
- 在线预约
技术维度对秒杀系统的分析 —— 架构原则
技术维度对秒杀系统的分析 —— 优化技术
业务维度对秒杀系统的分析
修改库存放在订单支付的前面位置 体现了企业的良心
秒杀没抢到的话 订单30分钟未支付会取消订单 释放库存 可以捡漏
核心业务基于DB的实现
场景描述
业务描述:有50台苹果7手机,模拟200个用户同时请求购买,每个人都购买N台手机
实现原理:基于数据库的乐观锁 表t_goods_info
update t_goods_info set amout = amout - #{buys} where code = #{code} and amout - #{buys} >=0
优点:实现简单, 最可靠
缺点: 并发量小 300 or 700
核心业务基于cache的实现(memcache)
场景描述
业务描述:有50台苹果7手机,模拟200个用户同时请求购买,每个人都购买N台手机
实现原理:基于缓存的乐观锁 。基于memcache的decr,decr是原子的。
decr是有毒的
Decr的返回值有只有三种情况,
“>0”“=0”(减数大于被减数) “=-1”(键值不存在)
10 – 100 =0(这里有毒)
Memcached是不支持事务的
操作序列不是原子性的
解决
轻量级的锁机制CAS机制
解释:Check and set ,即保存之前进行版本检查,memcache 1.2.4新增的特性。
- gets: 获取item,并获取版本号
- cas:更新item,并上传获取item时的版本号,版本号与服务器一致才能更新成功
算法如下:
核心代码:
@Override
public Boolean updateGoodsAmount(String code, int buys) {
MemcachedItem item = client.gets(code);
if(Integer.valueOf(item.getValue().toString().trim()) < buys ){
return false;
}else{
if(client.cas(code, String.valueOf(Integer.valueOf(item.getValue().toString().trim())-buys), item.casUnique)){
return true;
}else{
return updateGoodsAmount(code,buys);
}
}
}