推荐公众号
前言
公司为了推广自己的产品会进行很多促销互动,那在线上促销当然是秒杀互动了。实现秒杀的方式有很多种,例如将请求添加到mq中,将商品加载到redis中。我写的秒杀是商品加载到redis。
实现
思路
1.控制每个人每个商品 只能10s请求一次 (可根据业务酌情考虑,也可不加这条限制)
2.如果此人已经秒杀了该商品(查询该人该秒杀商品的订单),不允许再次秒杀
3.检查内存中商品是否售完,如果售完返回商品售馨
4.将redis中该商品个数 -1 如果返回的值小于0 表示商品已经售馨,将内存标记设为售馨
5.如果4返回值大于等于0 表示秒杀到改商品,创建秒杀订单
redis decr命令
官网介绍将制定key的值减1,返回减1后的值,当然也有很多异常具体看官网
decr
代码
String goodKey = appendString(miaoShaKey, goodId);
LocalDateTime beginTime = MS_BEGIN_TIME.get(goodId);
LocalDateTime now = LocalDateTime.now();
检查是否已经开始(根据业务考虑,可去掉)
if (now.isAfter(beginTime)){
return ResponseEntity.status(ResultStatus.MS_NOT_BEGIN.getCode())
.body(ResultStatus.MS_NOT_BEGIN.getMessage());
}
检查是否请求过于频繁
if (checkUserMsRequest()){
return ResponseEntity.status(ResultStatus.MS_REQUEST_TIMES.getCode())
.body(ResultStatus.MS_REQUEST_TIMES.getMessage());
}
检查是否已经秒杀到
if (checkUserMsOrder()){
return ResponseEntity.status(ResultStatus.MS_HAVE_GOOD.getCode())
.body(ResultStatus.MS_HAVE_GOOD.getMessage());
}
检查内存标记中是否已经售馨
Boolean goodSold = MS_SOLD_OUT.get(goodId);
if (goodSold){
return ResponseEntity.status(ResultStatus.MS_OVER_GOOD.getCode())
.body(ResultStatus.MS_OVER_GOOD.getMessage());
}
检查redis中是否已经售馨
Long stock = redisTemplate.opsForValue().decrement(goodKey);
if (stock < 0){
MS_SOLD_OUT.put(goodId, true);
return ResponseEntity.status(ResultStatus.MS_OVER_GOOD.getCode())
.body(ResultStatus.MS_OVER_GOOD.getMessage());
}
//到这里说明已经秒杀到商品 后面处理订单 通知其他服务
msService.handleOrder(userId, goodId);