秒杀系统设计 | 青训营笔记
这是我参与「第五届青训营 」笔记创作活动的第12天
今天的实践课程是关于秒杀系统的设计,通过本次课程,学习到了如何进行系统设计以及根据秒杀系统的设计实例掌握秒杀系统开发的方法。
课程重点内容
- 了解系统设计方法论
- 介绍了秒杀系统的设计核心
- 电商秒杀系统的实践
系统设计
如何评估一个系统
- 可用性
- 安全性
- 易用性
- 拓展性
- 耦合性
- 可维护性
- 性能
如何做系统设计
- 场景分析
- 存储设计
- 服务设计
- 可拓展性
如何发现系统的性能瓶颈
- 火焰图分析
- 链路追踪
- 性能测试
如何保证可用性与稳定性
电商秒杀业务介绍
商品:具有交易价值与属性的信息载体
SPU: Standard Product Unit
SKU: Stock Keeping Unit
秒杀业务的特点
- 瞬时流量高
- 读多写少
- 实时性要求高
秒杀业务的挑战
如何设计秒杀系统
场景
- 功能:活动发布、秒杀商品详情、秒杀下单
- 并发:参与人数多、QPS高
存储
多级缓存
分库分表
服务
- 子服务:用户服务、风控服务、活动服务、订单服务
- 基础组件:ID生成器、缓存组件、MQ组件、限流组件
扩展
系统架构图
课程实践
秒杀流程图
核心代码
-
创建秒杀活动
public ResponseData<?> createPromoActivity(@RequestBody CreateActivityRequest createActivityRequest) { Long start = createActivityRequest.getStartTime(); Long end = createActivityRequest.getEndTime(); if (start > end || System.currentTimeMillis() > start) { throw new BizException(ResponseEnum.ILLEGAL_ARGUMENT); } if (CollectionUtils.isEmpty(createActivityRequest.getPromoProducts())) { throw new BizException(ResponseEnum.ILLEGAL_ARGUMENT); } CreateActivityModel model = createActivityRequest.convert(PromoConverter::convertCreateActivityModel); List<CreatePromoProductModel> promoProductModels = hPromotionService.CreatePromoActivity(model); return ResponseData.Success(promoProductModels); }
-
获取秒杀活动商品详情 其中验证和风控服务使用了mock
public ResponseData<?> getProductDetail(@RequestParam(name = "promoId") Long promoId, @RequestParam(name = "skuId") Long skuId, @RequestParam(name = "spuId") Long spuId) { if (promoId <= 0 || skuId <= 0 || spuId <= 0) { throw new BizException(ResponseEnum.ILLEGAL_ARGUMENT); } String key = Constant.generatePromoProductKey(promoId, skuId, spuId); HPromoProductModel promoProductModel = cacheService.getVal(key); if (promoProductModel == null) { promoProductModel = hPromotionService.getPromotionProductDetail(promoId, skuId, spuId); } if (promoProductModel == null || !promoProductModel.checkPromo()) { log.error("promo activity not exist, params = {}", JSON.toJSONString(promoProductModel)); throw new BizException(ResponseEnum.ACTIVITY_NOT_EXIST); } log.info("get promo product detail success, res = {}", promoProductModel.getPromoId()); return ResponseData.Success(promoProductModel); }
-
创建秒杀订单
public ResponseData<?> createOrder(@RequestBody CreateOrderRequest createOrderRequest) { // 登录验证 mock if (createOrderRequest.getUserId() == null) { throw new BizException(ResponseEnum.USER_NOT_LOGIN); } // risk management if (!riskManagementService.riskManagement(createOrderRequest.getUserId())) { throw new BizException(ResponseEnum.USER_UNDER_RISK); } CreateOrderModel model = createOrderRequest.convert(PromoConverter::convertCreateOrderModel); OrderModel order = hPromoOrderService.createOrder(model); return ResponseData.Success(order); }
引用参考
「【实践课】手把手教你做系统设计」第五届字节跳动青训营 - 后端专场 (juejin.cn)
手把手教你做系统设计之秒杀系统 .pptx - 飞书云文档 (feishu.cn)