秒杀系统笔记
特点
1.抢购人数远多于库存,读写并发巨大
2.库存少,有效写少
3.写需强一致性,商品不能超卖
4.读强一致性要求不高
image.png
难点
稳定性难
高并发下,某个小依赖可能直接造成雪崩
流量预期难精确,过高也造成雪崩
分布式集群,机器多,出故障的概率高
准确性难
库存,抢购成功数,创建订单数之间的一致性
高性能难
有限成本下需要做到极致的性能
架构原则
稳定性
1.减少第三方依赖,同时自身服务部署也需做到隔离
2.压测,降级,限流方案,确保核心服务可用
3.需健康度检查机制,整个链路避免单点
高性能
1.缩短单请求访问路径,减少IO
2.减少接口数,降低吞吐数据量,请求次数减少
目标
满足高并发且高可用的秒杀系统
秒杀服务核心实现
设计:
1.满足基本需求,做到单服务极致性能(扣库存,查库存,排队等)
2.请求链路流量优化,从客户端到服务端每层优化
3.稳定性建设
基本需求
1.扣库存
2.查库存,排队进度
3.查订单详情,创建订单,支付订单
image.png
扣库存方案
1.下单减库存? 恶意下单&不会超卖
并发请求->创建订单->扣库存->支付
2.支付减库存? 订单超卖,订单支付不了
并发请求->创建订单->支付->扣库存
3.预扣库存?
并发请求->扣库存->创建订单->支付
预扣库存实现方案:
1.先扣除库存,然后创建订单,支付
2.10分钟内不支付则取消订单,避免不支付库存卖不出问题
极高并发下怎么做到单服务极致性能?
有效压榨CPU:
1.减少上下文切换(进程切换,线程切换,系统调用)
2.减少阻塞式I/O
I/O主要包含:
rpc调用(远程调用)
磁盘读写
无IO怎么做?
1.拆解-扣库存与写定点杆分开
2.用内存
3.用本地内存
image.png image.png image.png
预留buf,统一减库存
扣库存实现
1.初始化库存到本地库
2.本地减库存,成功则进行统一减库存,失败则返回
3.统一减库存成功则写入MQ,异步创建订单
4.告知用户抢购成功
php-fpm 多进程模型:
1.进程间改共享内存会出现强锁,改共享内存高会影响性能
创建,支付订单服务
1.与扣库存服务隔离
2.用户收到抢购成功,页面跳转到订单中心去支付订单
image.png
读商品信息页
1.与库存服务隔离
2.商品库一主多从提高读能力
3.页面静态化+缓存+db实现即可
如果创建订单海量,怎么解决高性能查排队进展的问题?
1.数组A存储排队中,待创建订单的用户;数组b用作索引,存储uid对应在数组A中的索引位置
2.每次从数组A中依次消费数据,并记录最近消费的索引值X
3.用户来查排队进展时,从hash表B中取出该uid对应存储的索引值Y
4.索引值Y-索引X = 排队进度值
image.png
高性能读库存
无I/O查库存怎么实现? (强一致性要求低)
1.读取本地库存,无则主动拉取一次,有则返回
2.异步脚本定时同步库存至本地
怎么做到漏斗型流量
客户端->接入层->server->数据
CDN架构,减轻客户端回源流量,预计能cache住90%读流量
读库存:客户端限制刷新频次,接入层限制同一用户请求次数,server分布式集群分摊流量
扣库存:客户端防重入,客户端限制刷新频次,验证码防刷削峰,
接入层限制同一用户请求次数,server分布式集群分摊流量