【系统设计】笔记

发布时间 2024-01-06 16:31:49作者: dddddcoke

4S 分析法(思路清晰法)

场景scenario: 和面试官沟通。features/QPS(每秒访问量)/DAU/Interfaces

服务service: 大系统拆分成小服务。

存储storage:数据如何存储和访问。缓存/数据库/file system

升级scale:解决缺陷,处理可能的问题。

 

【例子】秒杀系统

scenario:

QPS分析: 1000 -> 10000 100倍增加

流程

点击购买-> 是否开始->抢完了吗->展示购买->购买->创建订单->锁定库存成功->支付倒计时->按时支付成功->扣减库存->购买成功

service:

微服务架构

秒杀服务-秒杀数据库

商品信息和库存服务-商品数据库

订单服务-订单数据库

支付服务-支付数据库

storage:

商品信息表

商品id, name, desc, price

189,iPhone,xxx,5999

秒杀活动表

秒杀id, name,商品id,price, number

28,iPhone秒杀,189,4000,100

库存信息表

库存id, 商品id, 活动id(普通:0),库存,锁定(普通:0)

订单信息表

订单id, 商品id, 活动id, 用户id, 是否付款

数据流

商家侧: select commodity_info, insert seckill_info, insert stock_info

用户侧:select seckill_info, commodity_info, stock_info

insert order_info

update stock_info

 

事务开始,查询库存余量,并锁住数据,扣减库存,事务提交。

性能降低

大量请求访问Mysql

Mysql单点能支撑1000QPS,Redis支撑10wQPS,库存信息加载库到Redis

 

Redis: 将数据存储于内存中的非关系型键值对数据库(NoSQL),也可以讲数据持久化到磁盘中。单线程数据库,通过io多路复用实现并发。支持数据的主备荣宰。原子。内存中操作,性能极高。用作数据缓存。

预热:数据库读取秒杀活动信息,将商品库存预热到redis

读取redis,库存>0, -1,                                        锁定数据库库存创建订单(操作数据库)《数据库再检查一次》

(Lua脚本读redis库存并扣减)《投递消息到订单系统》

 

10w台秒杀数量:

redis请求慢一点,消息队列:一类基于生产者/消费者模型的组件,用于实现两个不同的系统之间的解耦和异步

生产者高速向消息队列中投递消息,消费者可以按照自己的节奏去消费生产者投递的消息。重试,可以持续投递,直到消费者消费成功。

 

库存扣减时机:

下单立即减库存:恶意下单,买不了

先下单,不减库存,支付成功后减库存:下单没减库存,下单成功但无法付款。

下单后锁定库存,支付成功后,减库存

 

如何限购:redis替代mysql

用户id是否在redis集合,将用户id加入redis集合

 

付款和减库存的数据一致性:分布式事务

三阶段提交,有超时机制

事务协调器:询问是否可以提交     是否可预执行(将undo, redo信息记录到日志)      提交(执行事务提交)

支付,订单,商品不同数据库

scale:

redis库存扣减完毕,请求直接拒绝

 

防止刷爆商品页面:

CDN(Content Delivery Network) ->前端资源静态化

CDN是依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

前端限流:点击一次后,按钮短时间内置灰。/限流器,跳转到繁忙页

如何计算倒计时:前端轮询服务器时间,并获取距离活动开始的时间差,以服务器时间为准

 

秒杀服务器挂掉?

尽量不要影响其他服务

服务雪崩

服务熔断:熔断该节点微服务的调用,快速返回错误的响应信息。