设计模式篇-2021春招准备

1、秒杀场景

title

隔离:

  • 系统隔离。系统隔离更多是运行时的隔离,可以通过分组部署的方式和另外99%分开。秒杀还申请了单独的域名,目的也是让请求落到不同的集群中。

  • 数据隔离。秒杀所调用的数据大部分都是热数据,比如会启用单独cache集群或MySQL数据库来放热点数据,目前也是不想0.01%的数据影响另外99.99%

动静分离:

title

  • 把整个页面Cache在用户浏览器
  • 如果强制刷新整个页面,也会请求到CDN
  • 实际有效请求只是“刷新抢宝”按钮

秒杀的动态数据和普通的详情页面的动态数据相比更少,性能也比普通的详情提升3倍以上。所以“刷新抢宝”这种设计思路很好地解决了不刷新页面就能请求到服务端最新的动态数据。

基于时间分片削峰:不让流量同时涌入,把峰值的下单请求给拉长了

  • 前端答题、验证码
  • 服务端通过锁或者队列来控制瞬间请求

限流:

  • Nginx限流

    Nginx官方版本限制IP的连接和并发分别有两个模块:

    • limit_req_zone: 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法。
    • limit_req_conn: 用来限制同一时间连接数,即并发限制。
  • 站点层限流
    • 单个部署实例的每秒最大请求数,每个用户每秒的最大请求或者通过Redis记录和限制单个用户只能请求一次。
  • 拒绝:当连接数过大,cpu负载达到90%,就拒绝请求

不要超卖

  • 下单减库存:一定不会出现超卖情况,但是有些人下单完不付款会影响其他人。

  • 付款减库款:付款减库存,可能会因为并发高导致付款时已经卖光,付不了款。

  • 预扣库存:最常用,如下单后扣库存,保留十分钟,在十分钟内未付款就不保留。如果付款时发现库存不足则不允许付款。

高并发系统

可以分为以下 6 点:

  • 系统拆分
  • 缓存: redis
  • MQ:Redis 来承载写那肯定不行,人家是缓存,数据随时就被 LRU 了,数据格式还无比简单,没有事务支持
  • 分库分表:将一个数据库拆分为多个库,多个库来扛更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高 sql 跑的性能
  • 读写分离:大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。
  • ElasticSearch:es 是分布式的,可以随便扩容,分布式天然就可以支撑高并发,因为动不动就可以扩容加机器来扛更高的并发。那么一些比较简单的查询、统计类的操作,可以考虑用 es 来承载,还有一些全文搜索类的操作,也可以考虑用 es 来承载

2、前后端分离,解决登陆问题

  • 前端把account和password,提交到服务端的登录api
  • 服务端验证正确后,生成一个token,并把token和userId,存在缓存里(推荐redis数据库),然后把token返回给前端
  • 前端每次的请求头中带token,这样就能够轻松的实现

3、面向对象编程6大原则

  • 单一职责: 一个类只负责一项职责
  • 开闭原则: 对程序的扩展是开放的; 对程序的更改是封闭的
  • 里氏替换: 子类型必须能够替换掉它们的父类型子类必须能够替换其基类
  • 依赖倒置: 针对接口编程,依赖于抽象而不依赖于具体
  • 接口隔离: 使用多个隔离的接口,比使用单个接口要好,使用多个小的专门的接口,而不要使用一个大的总接口
  • 迪米特法则: 最少知道原则,一个实体应当尽量少地与其他实体之间发生相互作用

设计模式篇-2021春招准备
https://zhangfuli.github.io/2021/02/26/2021春招准备-设计模式篇/
作者
张富利
发布于
2021年2月26日
许可协议