基于springboot、Redis搭建秒杀系统(一)

本文介绍了一个基于SpringBoot、Mybatis和Redis构建的秒杀系统,旨在通过实际项目巩固Redis知识。讨论了秒杀场景,如电商抢购、门票销售等,并强调了在高并发环境下防止超卖和防止黑产的重要性。文章详细阐述了保护措施,并逐步讲解了从数据库设计到代码实现的整个过程,包括配置、DAO、Service和Controller的开发,以及测试环节。

秒杀系统

前言

最近把redis基本的东西学的差不多了,但是没有做过什么具体的项目来实践,于是计划做一个项目来巩固知识。
本项目是一个整合springboot、mybatis、redis来做的一个秒杀系统。

1. 秒杀系统

1.1 秒杀场景

  • 电商抢购限量商品
  • 卖周董演唱会的门票
  • 火车票抢座 12306

1.2 为什么要做个系统

如果你的项目流量非常小,完全不用担心有并发的购买请求,那么做这样一个系统意义不大。但如果你的系统要像12306那样,接受高并发访问和下单的考验,那么你就需要一套完整的流程保护措施,来保证你系统在用户流量高峰期不会被搞挂了。

  • 严格防止超卖:库存100件你卖了120件,等着辞职吧

  • 防止黑产:防止不怀好意的人群通过各种技术手段把你本该下发给群众的利益全收入了囊中。

  • 保证用户体验:高并发下,别网页打不开了,支付不成功了,购物车进不去了,地址改不了了。这个问题非常之大,涉及到各种技术,也不是一下子就能讲完的,甚至根本就没法讲完。

1.3 保护措施有哪些

  • 乐观锁防止超卖 —核心基础
  • 令牌桶限流
  • Redis 缓存
  • 消息队列异步处理订单

2. 防止超卖

毕竟,你网页可以卡住最多是大家没参与到活动,上网口吐芬芳,骂你一波。但是你要是卖多了,本该拿到商品的用户可就不乐意了,轻则投诉你,重则找漏洞起诉赔偿。让你吃不了兜着走。

2.1 数据库表

-- ----------------------------
-- Table structure for stock
-- ----------------------------
DROP TABLE IF EXISTS `stock`;
CREATE TABLE `stock` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称',
  `count` int(11) NOT NULL COMMENT '库存',
  `sale` int(11) NOT NULL COMMENT '已售',
  `version` int(11) NOT NULL COMMENT '乐观锁,版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for stock_order
-- ----------------------------
DROP TABLE IF EXISTS `stock_order`;
CREATE TABLE `stock_order` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `sid` int(11) NOT NULL COMMENT '库存ID',
  `name` varchar(30) NOT NULL DEFAULT '' COMMENT '商品名称',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.2 分析业务

在这里插入图片描述

2.3 开发代码

配置文件

  • DAO

    public interface StockDAO {
        Stock checkStock(Integer id);//校验库存
        void updateSale(Stock stock);//扣除库存
    }
    
    public interface OrderDAO {
        void createOrder(Order order);//创建订单
    }
    
    
  • Service

    @Service
    @Transactional
    public class OrderServiceImpl implements OrderService {
        @Autowired
        private OrderDAO orderDAO;
        @Autowired
        private StockDAO stockDAO;
        @Override
        public Integer createOrder(Integer id) {
            //校验库存
            Stock stock = checkStock(id);
            //扣库存
            updateSale(stock);
            //下订单
            return createOrder(stock);
        }
        //校验库存
        private Stock checkStock(Integer id) {
            Stock stock = stockDAO.checkStock(id);
            if (stock.getSale().equals(stock.getCount())) {
                throw new RuntimeException("库存不足");
            }
            return stock;
        }
        //扣库存
        private void updateSale(Stock stock){
            stock.setSale(stock.getSale() + 1);
            stockDAO.updateSale(stock);
        }
        //下订单
        private Integer createOrder(Stock stock){
            Order order = new Order();
            order.setSid(stock.getId());
            order.setCreateDate(new Date());
            order.setName(stock.getName());
            orderDAO.createOrder(order);
            return order.getId();
        }
    }
    
  • Controller

    @RestController
    @RequestMapping("stock")
    public class StockController {
        @Autowired
        private OrderService orderService;
        //秒杀方法
        @GetMapping("sale")
        public String sale(Integer id){
            int orderId = 0;
            try{
                //根据商品id创建订单,返回创建订单的id
                orderId =  orderService.createOrder(id);
                System.out.println("orderId = " + orderId);
                return String.valueOf(orderId);
            }catch (Exception e){
                e.printStackTrace();
                return e.getMessage();
            }
        }
    }
    

2.4 正常测试

在正常测试下发现没有任何问题

首先在数据库中填入stock 的数据用来测试
在这里插入图片描述
运行程序后在浏览器输入在这里插入图片描述
结果返回为在这里插入图片描述
并且在stock_order表中成功生成order

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值