双十一亿级并发下秒杀框架及功能实现(一)

双十一亿级并发下秒杀框架及功能实现

1.秒杀电商微服务架构

在这里插入图片描述

2.要解决的问题

大并发情况下秒杀活动要解决的核心问题无外乎以下这几个
在这里插入图片描述
要解决这些问题,需要先清楚秒杀流程。
用户下单 --》 执行扣减库存业务逻辑 --》 更新数据库
活动秒杀活动的库存操作放哪?
如果用户都在数据库中进行操作,这么多用户频繁的操作数据库,肯定马上停工,所以我们将其放在redis中进行减库存操作。
数据库什么时候和redis进行同步?秒杀活动结束?用户下单完成?
很显然,等活动结束后再同步肯定不行,应在用户下单完成后就进行同步,但在同步过程很容易出现脏数据,这些问题都是要解决的

3.超卖少卖问题

解决超卖问题思路在于将并发变为串行,让其排队执行扣减,
少卖则是将下单失败的商品库存数量回滚
商品已卖完,并发下重复扣减,思路在于在拿到索资源时先判断秒杀是否结束

miaosha(){
//通过分布式锁来判断秒杀是否结束
int result =setnx("miaosha:end:商品id","用户id");//0代表结束,可设置过期时间,防止死锁发生
if(result == 0{
return "秒杀已结束";
}
//1.去redis中减库存
int count = redis.decr(“miaosha:store:商品id”);//对库存进行扣减并返回库存值,可能为-1
//2.询问库存是否充足
if(count < 0{
//setnx(""miaosha:end:商品id","用户id");//若锁设置了过期时间,为了防止过期发生超卖需重新上锁
redis.incr("miaosha:store:商品id");//让商品+1,使其变为0
return "库存不够,秒杀失败";
}
//3 创建订单
creatOreder();
redis.del("miaosha:end:商品id");//释放锁
return "秒杀成功"
}

//创建订单
createOrder(){
//创建订单,并通过消息队列方式调用其他服务
try{
//发消息,让库存服务去db中减库存,其他服务
}catch{
//如果服务失败,以为着秒杀失败
redis.incr("miaosha:store:商品id");//让商品数量+1
}

}

虽然redis可以解决超卖少卖问题,但是redis受带宽网速等因素影响较大,用户体验可能不是很好,我们是不是可以把库存操作放在同一台放在服务器而不是要去redis中取值再进行处理呢?

4.jvm缓存

为了提高性能,我们可以将缓存数据存入jvm中,将库存数量存入CurrentHashMap集合中
当服务器第一次被访问时,从redis中获取库存数量存入CurrentHashMap,之后访问者直接从CurrentHashMap中取库存数量

miaosha(){
//从jvm中获取秒杀是否已结束的标记
int result =map.get("商品id")if(result == 0{
return "秒杀已结束";
}
//1.去redis中减库存
int count = redis.decr(“miaosha:store:商品id”);//对库存进行扣减并返回库存值,可能为-1
//2.询问库存是否充足
if(count < 0{
map.put("商品id"0);//jvm缓存标记为0
redis.incr("miaosha:store:商品id");//让商品+1,使其变为0
return "库存不够,秒杀失败";
}
//3 创建订单
creatOreder();
redis.del("miaosha:end:商品id");//释放锁
return "秒杀成功"
}

//创建订单
createOrder(){
//创建订单,并通过消息队列方式调用其他服务
try{
//发消息,让库存服务去db中减库存,其他服务
int i = 库存-1;
map.put("商品id",i);
}catch{
//如果服务失败,以为着秒杀失败
map.put("商品id",1);//取消jvm秒杀结束缓存标记
redis.incr("miaosha:store:商品id");//让商品数量+1
}
}

这时会出现jvm不公平情况

5.多个jvm间的不公平情况

在这里插入图片描述

当线程0抢到最后一件商品时,这时redis会将其扣减为0,
如果线程0最终下单失败回滚商品库存的过程中,线程1和2访问服务器A和B进行抢购会得到一个秒杀已结束的结果,
但当线程0秒杀失败后,A服务器会将秒杀结束标记清除,及将库存改为1,而B服务器则不会清除标记
当线程3进行访问时,就会出现如果访问的是A或C服务器,可以得到还剩一件商品,而访问B服务器则得到秒杀已结束
这样就造成了jvm不公平的现象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值