Java秒杀系统--4.实现秒杀接口

简介

  实现秒杀接口

1.访问秒杀接口

  在秒杀商品详情页面中,点击立即秒杀按钮就可以访问秒杀接口了。

  onclick="getPath()" id="buyButton">开始秒杀</button>:调用getPath(),因为对秒杀接口进行了接口隐藏,所以要先获取path值,然后到url中,才能对秒杀接口进行访问。

2.后端处理获取path的请求,起到隐藏秒杀接口的功能

  

1 @AccessLimit(seconds = 120,maxCount = 5)
2     @RequestMapping(value = "/getPath",method = RequestMethod.GET)
3     @ResponseBody
4     public Result<String> getPath(Model model,MiaoshaUser user, @RequestParam("goodsId")long goodsId) {
5         String path = MD5Util.md5(UUIDUtil.UUID());
6         redisService.set(PathPrefix.Path,user.getId()+"_"+goodsId,path);
7         return Result.success(path);
8     }

path:一个随机字符串,然后进行一次MD5加密(MD5加密好像可有可无)得到的字符串。

对path使用了redis缓存。

3.前端获的path的值,开始访问秒杀接口

 

 1 success:function(data) {
 2             //获得path参数后,调用秒杀接口函数
 3             go_miaosha(data.data)
 4         },
 5 //调用秒杀接口
 6     function go_miaosha(path) {
 7         $.ajax({
 8             url:"/miaosha/"+path+"/do_miaosha",
 9             type:"POST",
10             data:{
11                 goodsId:$("#goodsId").val(),
12             },
13             success:function (data){
14                 if (data.code==0){
15                     getResult($("#goodsId").val());
16                 }else layer.msg(data.msg)
17             },
18             error:function () {
19                 layer.msg("客户端有误1")
20             }
21         });
22     }

4.后端秒杀接口

  第一个验证:限制某个用户在5秒钟内,不能调用该接口超过5次,并且必须进行登录。

  @AccessLimit(seconds = 5,maxCount = 1,needLogin = true)

  第二个验证:验证url中的path值是否相同,path为一个字符串,被存储在redis中,key由userId和goodsId构成,生存期为60秒。

  访问redis得到其中存储的path值,然后进行比较。

  

1 @AccessLimit(seconds = 120,maxCount = 5)
2     @RequestMapping(value = "/getPath",method = RequestMethod.GET)
3     @ResponseBody
4     public Result<String> getPath(Model model,MiaoshaUser user, @RequestParam("goodsId")long goodsId) {
5         String path = MD5Util.md5(UUIDUtil.UUID());
6         redisService.set(PathPrefix.Path,user.getId()+"_"+goodsId,path);
7         return Result.success(path);
8     }

  第三个验证:验证商品的库存数量,利用afterPropertiesSet方法,在spring容器初始化时将数据库中的商品数量缓存到redis中。

  

 1 //该方法在初始化之前执行,将数据库中的商品库存缓存到redis服务器中
 2     private Map<Long,Boolean> goodsStatus = new HashMap<>();
 3     @Override
 4     public void afterPropertiesSet() throws Exception {
 5         List<GoodsVo> goodsList = miaoshaGoodsService.getGoodsList();
 6         for (GoodsVo goods:goodsList
 7              ) {
 8             long id = goods.getId();
 9             long stock = goods.getStockCount();
10             goodsStatus.put(id,false);
11             redisService.set(GoodsPrefix.getGoodsStack,""+id,stock);
12         }
13     }

  当redis中的商品库存被减到零后,所有后来的秒杀请求均被拒绝,并且只会触发一次集合的get操作,连redis操作也不会触发。

  

1     if (goodsStatus.get(goodsId)) {
2             return Result.error(CodeMsg.SECKILL_OVER);
3         }
4         long stock = redisService.decr(GoodsPrefix.getGoodsStack, "" + goodsId);
5         if (stock < 0) {
6             goodsStatus.replace(goodsId, true);
7             return Result.error(CodeMsg.SECKILL_OVER);
8         }

  第四个验证:验证是否包含该用户秒杀该商品的订单,每当完成一次秒杀。都将秒杀订单缓存到redis中,方便快速验证。

1                                                                                                                         //验证4.判断是否有该用户和该商品的订单存在
2         MiaoshaOrder miaoOrder = redisService.get(OrderPrefix.getGoodIdAndUserId, "" + user.getId() + goodsId, MiaoshaOrder.class);
3         if (miaoOrder != null) {
4             return Result.error(CodeMsg.REPEATE_SECKILL);
5         }

  使用rabbitmq将秒杀操作信息封装发送到接收端,然后执行秒杀的动作。使用MiaoshaMessage.class来封装秒杀操作信息。

1 import lombok.Data;
2
3 @Data
4 public class MiaoshaMessage {
5     private MiaoshaUser miaoshaUser;
6     private long goodsId;
7 }
1      MiaoshaMessage mm = new MiaoshaMessage();
2         mm.setGoodsId(goodsId);
3         mm.setMiaoshaUser(user);
4         mqSender.sendMiaoshaMessage(mm);

  在监听器端还有验证一下数据库中记录的库存,然后再执行秒杀,第五个验证:验证数据库中的商品库存数量。

@RabbitListener(queues = MQConfig.MIAOSHA_QUEUE)
    public void reciveMiaosha(String msg) {
        MiaoshaMessage mm = RedisService.strToBean(msg, MiaoshaMessage.class);
        MiaoshaUser user = mm.getMiaoshaUser();
        long goodsId = mm.getGoodsId();
                                                                                                                        //通过数据库中的数据来判断库存的多少
        GoodsVo goodsVo = miaoshaGoodsService.getGoodsVoById(goodsId);
        int kucun = goodsVo.getStockCount();
        if (kucun == 0) {
            return;
        }
        //进行数据库中的秒杀操作
        miaoshaService.miaoSha(user.getId(), goodsId);
    }

5.使用MiaoshaService.class中的miaoSha(long useId, long goodsId)方法来完成秒杀工作。

  在该方法上使用@Transactional标签,当事务来处理。总共分为3大步,减库存,下订单,redis缓存秒杀订单。

  

 1 @Transactional
 2     public OrderInfo miaoSha(long useId, long goodsId) {
 3                                                                                                                         //减库存,并设置减库存的结果
 4         boolean reduceResult=miaoshaGoodsService.reduceStock(goodsId);
 5         setReduceResult(goodsId,reduceResult);
 6         miaoshaGoodsService.reduceFMStock(goodsId);
 7                                                                                                                         //下订单
 8         orderInfoService.createOrder(useId,goodsId);
 9         long orderId = orderInfoService.getByUserIdGoodsId(useId,goodsId).getId();
10         MiaoshaOrder miaoshaOrder = new MiaoshaOrder();
11         miaoshaOrder.setMiaoshagoodsId(goodsId);
12         miaoshaOrder.setOrderId(orderId);
13         miaoshaOrder.setUserId(useId);
14         orderInfoService.createMiaoshaOrder(miaoshaOrder);
15                                                                                                                         //为秒杀订单做一个redis缓存
16         redisService.set(OrderPrefix.getGoodIdAndUserId,""+useId+goodsId,miaoshaOrder);
17         return orderInfoService.getByUserIdGoodsId(useId,goodsId);
18     }

至此秒杀功能基本完成。

  

 

  

原文地址:https://www.cnblogs.com/deijiawoyu/p/12669131.html

时间: 2024-08-30 18:34:30

Java秒杀系统--4.实现秒杀接口的相关文章

秒杀系统:并发队列 接口设计 并发请求数据安全处理

看秒杀系统的时候看到的关于并发队列的介绍,摘抄如下 并发队列的选择 Java的并发包提供了三个常用的并发队列实现,分别是:ArrayBlockingQueue.ConcurrentLinkedQueue 和 LinkedBlockingQueue  . ArrayBlockingQueue是初始容量固定的阻塞队列,我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品,那么我们就设定一个10大小的数组队列. ConcurrentLinkedQueue使用的是CAS原语无锁队列实现,是一个异步

秒杀系统架构设计

秒杀活动的用户量可能是网站平时正常访问量的数百甚至上千倍,网站如果为了秒杀时的最高并发量而设计部署,就需要比正常运营多的多的服务器,而这些服务器在绝大部分时候都是用不着的,浪费惊人.所以秒杀业务不能使用正常网站的业务流程,也不能与正常网站业务共用服务器,必须设计部署专门的秒杀系统. 秒杀系统所面对的技术挑战: 1.对现有业务造成冲击 2.高并发下的应用.数据库负载 3.突然增加的网络及服务器带宽 4.直接下单 秒杀规则是到点了才能下单,而下单页面也只是一个普通的url,如果得到这个url则不用等

Python Django 集成Redis Sentinel(哨兵)集群开发秒杀系统

我们知道秒杀系统最大特点是瞬时高并发.高访问量的系统.我们还要保证它的高可用性.这里我们采用Python Django 集成Redis Sentinel(哨兵)集群开发秒杀系统. Redis Sentinel(哨兵)集群Redis哨兵为Redis集群提供了高可用性.实际上这意味着我们可以使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis集群部署.可大大提高系统的高可用性. 哨兵模式还提供了其他的附加功能,如监控,通知,为客户端提供配置. 下面是在宏观层面上哨兵模式的功能列表: 监控:

秒杀系统的思考方式与设计思路--左手隔离,右手分层

大家好,我是崔皓. 很高兴有这样一个机会和大家认识.我在IT行业从事软件开发工作十余年了,足迹涵盖企业服务,互联网,企业数字化转型等.工作之余热爱阅读和学习,希望能通过这个专栏和大家成为朋友. 开篇 本次专栏要给大家分享的是"如何设计秒杀系统",专栏共包括15章,本章是第一章.今天会给大家介绍以下内容: 秒杀场景的特征 隔离的设计思路 分层设计思路本章的讲解思路是,提出秒杀场景的特征,也就是理解什么是秒杀.然后介绍在秒杀系统设计的底线,有了底线才能保证进可攻退可守.最后介绍使用哪些方法

Java秒杀系统实战系列~商品秒杀代码实战

摘要: 本篇博文是"Java秒杀系统实战系列文章"的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即"商品秒杀"功能模块的代码实战. 内容: "商品秒杀"功能模块是建立在"商品详情"功能模块的基础之上,对于这一功能模块而言,其主要的核心流程在于:前端发起抢购请求,该请求将携带着一些请求数据:待秒杀Id跟当前用户Id等数据:后端接口在接收到请求之后,将执行一系列的判断与秒杀处理逻辑,最终将处理结果返回给到前端.

Java秒杀系统实战系列~整合RabbitMQ实现消息异步发送

摘要: 本篇博文是“Java秒杀系统实战系列文章”的第八篇,在这篇文章中我们将整合消息中间件RabbitMQ,包括添加依赖.加入配置信息以及自定义注入相关操作组件,比如RabbitTemplate等等,最终初步实现消息的发送和接收,并在下一篇章将其与邮件服务整合,实现“用户秒杀成功发送邮件通知消息”的功能! 内容: 对于消息中间件RabbitMQ,想必各位小伙伴没有用过.也该有听过,它是一款目前市面上应用相当广泛的消息中间件,可以实现消息异步通信.业务服务模块解耦.接口限流.消息分发等功能,在微

Java高并发秒杀系统API之SSM框架集成swagger与AdminLTE

初衷与整理描述 Java高并发秒杀系统API是来源于网上教程的一个Java项目,也是我接触Java的第一个项目.本来是一枚c#码农,公司计划部分业务转java,于是我利用业务时间自学Java才有了本文,本来接触之初听别人说,c#要转java很容易,我也信了,但是真正去学习的时候还是踩了无数个坑,好在朋友有几个做安卓的,向他们讨教了一些经验,但是他们做安卓的和web又是两个方向,于是继续一个人默默采坑避雷之旅,首先上手的是下面这个Java高并发秒杀系统API. 学习java的初衷一个是公司转行,二

Java秒杀系统方案优化---高性能高并发实战

Java秒杀系统方案优化---高性能高并发实战网盘地址:https://pan.baidu.com/s/1htNv2zq 密码: ssyt备用地址(腾讯微云):https://share.weiyun.com/889808c023b6e9d9f504399a5b07276f 密码:1WaUHB 亮眼的!高并发秒杀系统核心技术 课程以"秒杀"场景为例,但技术都是通用的,举一反三,方得始终应对大并发:多层次多粒度缓存+消息队列异步+服务器分布式部署 专业的压测工具:有依有据,鉴证系统的优化

Java电商秒杀系统深度优化 从容应对亿级流量挑战

第1章 课程导学[学前须知]本章对这门课程进行说明,包括:电商秒杀场景的介绍.秒杀系统涉及模块的介绍,秒杀核心的知识点的介绍,课程的学习规划等. 第2章 秒杀项目框架回顾[秒杀免费课程场景解析,源码走读]本章会介绍前期秒杀免费课程当中所涉及的基础框架搭建知识,项目分层,源码导读等,帮助大家更快的理解秒杀的基础项目,为后续更深一步的课程学习打基础.如果小伙伴们对免费课相关内容已经非常熟悉,可以跳过此章! 第3章 云端部署,性能压测[从本地调试到云端上线的必经之路]本章结合前面的秒杀项目介绍了他在云