这是我参与[第五届青训营]伴学笔记创作活动的第10天。
课程内容:
- 系统设计方法论
- 电商秒杀业务介绍
- 课程实践
- 课程总结
01.系统设计方法论
系统设计的那些问题
- 为什么要做系统设计
- 个人:面试、个人能力提升、拓展技术视野
- 工作:业务驱动、系统重构、突破和创新
- 系统设计的定义是什么
- 系统:关联的个体、规则运作、组成工作的整体
- 设计:设想和计划、目的、过程安排
定义:为了达成某个目的,通过个体组成整体的过程。 3. 怎么做系统设计,如何落地一个系统
4S分析法
- 场景分析:什么系统,需要哪些功能,大多的并发量
- 存储设计:数据如何组织,sql存储,nosql存储
- 服务设计:业务功能实现和逻辑整合
- 可扩展性:解决设计缺陷,提高鲁棒性、扩展性
- 系统功能实现之后,如何分析瓶颈并优化
- 火焰图分析:针对单个实例的分析,cpu的使用、内存的使用,找出代码上的瓶颈
- 链路追踪:在服务中对同一个请求做追踪,知晓哪个请求做了什么服务以及耗时多少
- 性能测试:找出整个系统性能的不足
- 如何验证系统的可用性和稳定性
- 链路梳理:核心链路、流量漏斗、强弱依赖
- 可观测性:链路追踪、核心监控、业务报警
- 全链路测试:压力测试、负载测试、容量测试
- 稳定性测试:系统限流、业务兜底、熔断降级
- 容灾演练:混沌工程、应急 手册、容灾预案
02.电商秒杀业务介绍
电商介绍
- 供给测
- 消费者侧
- 交易环境
- 商品:具有交易价值和属性的信息载体。
- SPU:标准的产品单元。
- SKU:库存保持单元。
秒杀业务的特点
- 瞬时流量高
- 读多写少
- 实时性要求高
秒杀的挑战
- 高性能
- 资源成本
- 反欺诈
- 流量管控
- 鲁棒性
- 扩展性
- 防止超卖
1. 场景
功能
- 秒杀活动发布
- 秒杀商品详情
- 秒杀下单
并发
- 万人参与秒杀
- QPS 1w+
- TPS 1k+
2. 存储
三级存储:mysql-redis-localcache
3.服务
子服务
- 用户服务
- 风控服务
- 活动服务
- 订单服务
基础组件
- ID生成器
- 缓存组件
- MQ组件
- 限流组件
4.扩展
- 流量隔离
- CDN
- 缓存优化
- 流量管控
- 数据库扩展
- MQ扩展
- Redis扩展
- 服务水平扩展
- 服务垂直扩展
系统架构图
03.课程实践
秒杀流程图
代码讲解
- common:定义的基础东西,枚举以及一些常量
- config:redis的一些配置
- convertet:数据转换
- controller:spring boot里面常规的controller
- dao:数据库操作
- entity:数据库实体
- enums:枚举
- handler:异常处理
- limit:限流组件
- lock:分布式侧组件
- model:一些数据模型
- mq;生产者与消费者
- service:业务逻辑层,包括server接口与实现
- util:基础工具
controller
活动
首先创建一个秒杀活动接口activityActivity。
商品信息
限流组件所用
校验开始时间与结束时间,校验失败就抛出异常。
请求通过就将请求转换一个model,即业务领域。
convert是定义在request里的一个方法,传进来一个函数编程function。
cinvertCreateActivityModel转换函数(java内比较优雅的写法-函数式编程),使用builder插件。
转换为model后,进行业务操作,即直接创建一个活动CreatePromoActivity。
CreatePromoActivity。
把前面传进来的model转换成一个实体HPromo
对应数据库内的活动的表
合法性校验:
- id生创建组件生成活动id,放入数据库,如果写失败则返回失败给端上。
- 成功后需要从model取出来本次活动需要秒杀的商品。
- 再把spuid取出来放入set里面,set内为空则返回创建失败。
- set不为空则转换为list,在数据库内查询该商品。若商品不存在与数据库,则返回错误。
- 校验商品状态,如果已经下线则也不合法。
- 过滤掉已经售卖商品。
扣除库存。successlist是扣除成功的list,遍历promoProducts。decreaseStock。
其中调用的hSkudao来扣减库存
decreaseStock的sql语句。条件是防止超卖,已有库存大于扣减的库存。
扣减库存成功后,缓存至generatePromoteStockey。
给一个参数k代表秒杀商品库存,缓存预热思想。
校验successlist是不是空,空则错误;非空后,批量插入。
活动详情
前端有一个秒杀会场。简单校验
商品详情缓存
k的处理。
从缓存获取k,若获取失败,则在数据库寻找;若仍为空,则校验活动状态。
获取详情的业务逻辑
获取活动商品
校验spu
获取sku
下单 登录界面与风控校验首先下单请求转换为一个model
从秒杀商品sku中构建库存
问题:get decrease不是原子,decreaase是原子的,但不可以,回补的库存无法供用户消费。
解决办法前端传过来的价格不置信,所以必须从后端获取
支付金额、方式、状态与订单创建(未支付状态),创建时间与更新时间
使用mq,优化性能
JSON序列。创建完消息后,直接生产者做send,判断是否send成功。
配置
线程数的配置(800较500合适,通过压测最终确定)日记格式配置
数据库配置
redis配置
......
组件
限流组件。定义数量与时间。......
分布式锁
解锁(通过脚本)close(在抽象父类定义)做自动解锁
加锁用的是UUID,使得每个锁不同,防止误删
......
ID生成器(雪花算法)
......
课程总结
- 服务无状态
- 批量写入
- 最终一致性