毕业设计电商秒杀系统
业务背景
为了给平台带来用户量,并提高平台知名度,公司决定在 6.18 推出秒杀活动:
1)秒杀商品包括 1000 个充电宝,10 台 iPhone12,分别在 6 月 18 日早上 8:00 以及 20:00 开抢;
2)日常日活用户 100w。
约束和限制
技术限制
技术团队有 30 人,后端 15 个,以 Java 为主,已落地微服务架构;
秒杀活动必须在 App 端进行;
目前只有单机房。
成本限制
资金控制在 15w 以内。
时间限制
为了让更多人能参与进来,老板决定充电宝和 iPhone 秒杀时间分别定在 6.18 的晚上 20 点及 21 点整;
活动开始前,必须完成系统测试,预演,上线以及相关数据预热,必须确保系统稳定。
总体架构分析:
关键架构分析
存储和计算性能分析
假设百万日活用户中按照 30%用户:即 30w 的用户参与秒杀,同时又吸引了约 15w 新用户进入注册并且参与秒杀,80%的用户在活动前 30 秒开始进入商品详情页面。
商品详情页:两个产品文字信息共 1k,各 4 张 200k 大小的宣传图,加上其他压缩后的样式及 JS 等静态资 100k,则共有(200*4+100)*2≈1.76Mb ,总流量大概为(30w+15w)*1.76Mb=773.44G;
商品浏览:秒杀开始前,页面上显示倒计时并禁止抢购按钮,商品详情页提前加入 CDN 缓存,当用户进入商品页面时,直接从 CDN 中获取相关静态资源的内容并缓存到本地中,峰值 QPS 为(30w+15w)*80%/30=1.2w;
秒杀查询:秒杀前在商品详情页上每秒向后端发两次请求获取秒杀活动是否开始,并验证用户的购买资格以及当前库存,则可得峰值 QPS 为 2*(30w+15w)*80%/30=2.4w;
秒杀抢购:秒杀开始后即向后端发送动态生成的秒杀 url,大部分用户会不断点击秒杀按钮,为减少无效请求产生,App 端将限制一秒只能触发一次请求,并随机只允许 20%的请求通过,其余均会被 App 端抛弃,则峰值 TQS 为(30w+15w)*80%*20%=7.2w;
下单:生成订单,并预占库存,系统只纪录成功下单的信息,则共有 1000+10=1010 条订单纪录,峰值 TPS 相同;
支付:有效时间内完成支付,即可视为秒杀完成,否则回填库存;
存储架构分析
面对 1.2w 次的峰值 QPS, 将相关静态资源提前加入到 CDN 缓存中,并且减少相关对系统的压力;
商品信息、秒杀状态可缓存在 App 本地中,减少重复服务端的数据请求;
假设每个用户都会抢购两种产品,抢购失败/取消购买类订单不保存纪录,则共有订单纪录 1000+10 条,可先保存到 Redis 中,再异步保存到保存 MySQL 即可;
计算架构分析
抢购状态,商品库存数分别缓存到 Redis 中,并通过 Lua 进行原子修改;
由于单机房则可考虑三级负载均衡方案,无须考虑 DNS 以及成本较高的 F5;
总体架构
数据存储架构设计
负载均衡架构设计
缓存架构设计
高可用架构设计
详细设计
关键设计
1)将 Redis 提前缓存好秒杀活动状态,商品库存信息,前端请求直接读取 Redis 中的缓存,避免请求压坏 MySQL;
2)利用双消息队列对秒杀请求进行削峰排队,等待队列长度为 5 倍订单总数,即 1010*5=5050,主队列长度设置为 1 倍订单总数。判断逻辑为,前端请求先进入等待队列,如果主队列未满,则将请求推进主队列中,否则直接将其他请求返回继续等待,页面显示继续排队;主队列消费者判断库存情况,如果还有则开始下单并扣库存,并进入支付阶段,无则将请求放回队列;当支付失败/取消时,将该消息从主队列中移除,并回填库存;
3)库存的更新均通过 Redis + Lua 实现;
4)秒杀成功后将订单信息保存到 Redis 中再异步保存到 MySQL 中。
设计规范
框架以及工具
后端采用 SpringBoot 2.6.2 +Spring Data JPA +Spring Security,并支行在 Tomcat 上;
数据库 MySQL 使用 Innodb 存储引擎;
缓存使用 Redis 缓存
质量设计
可测试性
所有功能必须有对应的单元测试,集成测试,且行测试覆盖率至少 85%,方法覆盖率至少 90%;
可维护性
为管理员提供必要接口及权限,可重启服务/系统;
提供异常通知功能,当系统异常时可通过短信或微信通知到管理员;
可观测性
后台提供系统管理面板,显示当前系统 CPU,内存,硬盘,网络及各系统在线情况;
演进规划
一期
由于时间限制,一期实现基本上的秒杀系统功能即可,包括商品上线管理,订单功能,支付功能;
二期
根据业务需求进一步实现风控服务
增加预约模块并结合风控服务,进一步提升用户体检。
评论