秒杀项目
秒杀项目
软件架构
技术 | 版本 |
---|---|
SpringBoot | 2.6.13 |
MyBatis Plus | 3.5.2 |
MySql | 8 |
Redis | 7.2 |
RebbitMQ | 3.13.3-management |
数据库表
基础功能
登录页
LoginController
商品列表页
GoodsController
商品详情页
SeckillOrderController
订单详情页
OrderController
秒杀功能
大致经过三个阶段的优化
- 在该项目中核心就是秒杀的实现:不能超卖、不能重复抢
- 不能超卖在doSeckill中通过update的排他性实现(乐观锁)。而在doSeckill1中通过redis预减库存(redis的原子性实现)
- 不能重复抢通过唯一索引实现,默认建表时没有添加,压测可以把用户加少点商品多一点就可以复现重复购买
- 优化不过就是把数据库的重复访问,能放到redis就放到redis;而如果访问redis太多了就再加一层内存标记
- redis和mysql要么都在远程,要么都在本地,否则可能会出现redis缓存优化了但QPS没提升
秒杀的接口有三个
- doSeckill:update排他+唯一索引实现秒杀 解决超买超卖
1 | // 到这里为了实现不超卖(减少库存的同时判断库存数量)且单一下单(唯一索引) |
2.doSeckill1:redis预减库存 + 内存标记 + MQ+前端轮询 提高qps
1 | //用redis预减库存(减少数据库访问),redis是原子操作,可以防止超卖,并减少redis访问次数:引入内存标记 |
3.doSeckill2:最终秒杀方案 一些安全上的优化(验证码,限流)
压测
准备用户
使用utils包下的UserUtil生成模拟用户(把用户信息存放到mysql数据库中并生成config.txt用于压测时设置CSV数据文件,并把用户信息ticket存放在redis中,因为有拦截器每次进入任意接口都需要校验用户ticket)
压测过程
测试计划->添加线程组
线程组->添加配置元件->HTTP默认请求
线程组->添加配置元件->HTTP Cookie 管理器
线程组->添加配置元件->CSV Data Set Config
线程组->取样器->HTTP请求
线程组->监听器->聚合报告/查看结果树
压测结果
- QPS:每秒请求次数
- TPS:每秒事务(吞吐量)次数
- 一个页面一个TPS可能多次QPS
/seckillorder/doseckill接口 压测结果 1955.2
/seckillorder/doseckill1接口 压测结果 5841.1
可以看到提升还是比较明显的,这得益于我们使用redis预减库存 + 内存标记 + MQ提高了qps
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 houWenk's Blog!