springboot 秒杀系统(一)

秒杀系统应该是很检验一个人的能力的项目。包括从前端

到运营商到nginx到后端等等,很多地方可以优化。

前端的页面控制,运营商的CDN加速,nginx的动静分离等

下面我来一步一步实现后端的秒杀功能的一步一步实现和优化。

后端接口

1,获取商品详情,2,秒杀接口

获取商品:参数 商品ID        通过商品ID返回商品详情。

秒杀接口:参数 商品ID        后端接收商品ID,判断是否有库存,

          没有:返回已售完   

          有:库存-1,创建订单,返回秒杀成功

测试工具   jmeter  测试这2个接口的QPS(每秒处理请求数)

期望结果: 商品能够正常秒杀,不能出现超卖等异常,QPS越高越好。

1.0版本: 不借用其他中间件和优化,正常的操作数据库。实现功能

/**
     * 秒杀一般只限购1个,所以数量都是1
     * @return 1 成功 0 失败
     */
    public int secKill(String seckillId,String userid){
        /**
         * 第一步:判断当前时间是否在秒杀时间段内
         * 第二步:判断是否有库存:有  库存减一  没有直接返回售完
         * 第三步:创建订单,返回成功
         */
        //判断当前时间是否在秒杀时间段内
        JSONObject jsonObject = productService.findById(seckillId);
        if(jsonObject==null){
            return 0;
        }
        if(judgeTime(jsonObject.getTimestamp("starttime"),jsonObject.getTimestamp("endtime"))){
            return 0;
        }
        //更新库存减一,成功返回1,失败返回0
        int isSelfOut = productDao.updataNumById(seckillId);
        if(isSelfOut==0) {
            return 0;
        }
        //创建订单
        orderDao.createOrder(seckillId,userid);
        return 1;
    }

    /**
     * 如果当前时间在秒杀时间端,返回false,不在返回true
     * @param starttime
     * @param endtime
     * @return
     */
    private boolean judgeTime(Timestamp starttime, Timestamp endtime) {
        Date date = new Date();
        return !(date.getTime()>starttime.getTime()&&date.getTime()<endtime.getTime());
    }

判断是否有库存,有 减一 SQL<!-- 这里做判断是否有库存和数量减一操作,
如果库存大于1,则 更新记录返回 1
如果库存等于,更新失败,返回 0
所以是不会出现超卖的现象-->
<update id="updataNumById">
update seckill set inventory=inventory-1
where seckillId=#{seckillId} and inventory>0
</update>

秒杀商品表 :ID,商品名,库存数,开始时间,结束时间:

测试计划jmeter并发1000。获取商品传入商品ID,秒杀接口传入商品ID和随机11位用户ID

测试结果:  如下图,商品接口 qps 110   秒杀 qps 68,这个跟电脑配置有关。

订单表500表记录,商品表1000的库存变为0,没有出现超卖现象,逻辑正常,数据一致性

第一个版本是正常的没有借用其他组件的,下个博客在此基础上一步步优化。

猜你喜欢

转载自blog.csdn.net/shrek11/article/details/103489397