该部分设计开发完成,已解决测试出的所有并发问题,同时单机测试下QPS大致为1000
围绕秒杀下单完成前端-后端-数据库的设计与开发,实现一个高可用大并发的秒杀系统
用户登录 -> 查看秒杀商品页 -> 查看秒杀商品详情页 -> 下单秒杀 -> (处理秒杀消息,支付暂略过) -> 查询秒杀结果
- 用户登录 双重加密:password = MD5(MD5(明文密码 + 前端固定salt) + 数据库字段中特定salt)
- 查看秒杀商品页、秒杀商品详情页 页面静态化:页面作为静态资源给出,配置cors跨源访问,前后端数据对接使用ajax通信,降低后端负载,提高安全性
- 下单秒杀 用户限购: 快速拦截重复抢购,redis查询是否存在uid+seckillid的组合
- 处理秒杀消息 redis分布式锁: 锁定uid+seckillid组合,避免rabbitmq多线程同时生成多份同人同秒杀商品的订单,破坏限购规则
- 查询秒杀结果 前端定时轮询: 异步处理,前端每秒轮询一次后端是否处理完秒杀请求
登录状态保存:使用随机生成的32位token作为登录凭证,前端存在cookiee, 后端存在redis中
库存充足判断: redis预减库存,降低数据库压力,内存空库存标记,降低redis压力
发送秒杀消息: 向rabbitmq队列发送秒杀消息,异步处理,流量消费,提高秒杀模块的响应能力
数据库唯一索引: 确保永远不会插入重复抢购的订单,同时加速重复抢购的查询
扣减库存原子操作: 自定义mybatis语句,将检查并扣减库存作为一个sql语句执行,避免上行锁/开启事务处理多sql影响效率
笔记本: windows10,四核八线程,基准速度2.11GHZ
应用、redis、mysql、jmeter都放在一台笔记本上,rabbitmq放在低配置云服务器上
使用jmeter测试,预先对jvm预热,同时调整连接池等参数,jmeter的参数设置:ramp-up time为5s(缓启动)
线程数设置为10000,秒杀商品库存数100,模拟10000个用户再5s内依次抢购该商品
如上图,线程平均响应时间 5 ms, 95%的线程在18ms内完成,吞吐量达到996
结论:目前秒杀项目每秒能稳定处理900~1000个秒杀请求, 在html报告中页可以看出没有发生阻塞
但因为单机资源有限,如果再加大线程数就会超过处理中的线程和最大等待队列数的总和,导致出现连接被断开的错误
因此项目下一版的迭代方向是向分布式设计,见micros分支。