如何设计秒杀系统(二)

实施方案

热点数据

  1. 分类:
    静态热点数据,可以提前预测的热点数据,可以提前缓存。
    动态热点数据,一般是突发的临时的。
  2. 如何发现热点数据
    可以通过运营手段提前报名来发现静态热点数据,也可以通过数据统计出TOPN的商品。
    发现动态热点数据:
    构建一个异步的系统,它可以收集交易链路上各个环节中的中间件产品的热点 Key,如 Nginx、缓存、RPC 服务框架等这些中间件(一些中间件产品本身已经有热点统计模块)。
    建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统(包括详情、购物车、交易、优惠、库存、物流等)访问的时间差,把上游已经发现的热点透传给下游系统,提前做好保护。比如,对于大促高峰期,详情系统是最早知道的,在统一接入层上 Nginx 模块统计的热点 URL。
    将上游系统收集的热点数据发送到热点服务台,然后下游系统(如交易系统)就会知道哪些商品会被频繁调用,然后做热点保护。
    在这里插入图片描述
    注意事项:
    1. 日志抓取采用异步的方式,即保证通用性也不影响主流程。
    2. 应用和组件间要有自己的限流保护措施。
    3. 热点发现要快(3s)
      热点数据的处理:
      对热点数据利用LRU队列进行缓存
      把热点请求和普通请求进行隔离,防止热点数据影响到普通的请求
      (业务隔离,系统隔离,数据隔离)。

削峰错谷

为什么要削峰:

  1. 节省服务器资源
  2. 让服务端处理变得更加平稳
    怎么做:
    1.排队
    消息对立
    线程加锁,排队等待
    内存排队算法
    顺序读文件
    2.答题
    系统设计思路:
    在这里插入图片描述
    答题验证设计:
    在这里插入图片描述
  3. 分层过滤
    在这里插入图片描述
    依次走浏览器缓存,CDN,统一cache,后台,数据库
    原则:
    将动态请求的读数据缓存(Cache)在 Web 端,过滤掉无效的数据读;
    对读数据不做强一致性校验,减少因为一致性校验产生瓶颈的问题;
    对写数据进行基于时间的合理分片,过滤掉过期的失效请求;
    对写请求做限流保护,将超出系统承载能力的请求过滤掉;
    对写数据进行强一致性校验,只保留最后有效的数据。

系统性能优化

  1. 概述
    一般用QPS来衡量性能,总 QPS =(1000ms / 响应时间)× 线程数量
    响应时间:
    响应时间一般由CPU执行时间和线程等待时间组成,优化线程等待时间对性能影响不大,要做的是增加CPU的执行时间。
    线程数:
    默认配置,线程数 = 2 * CPU 核数 + 1
    最佳实践得出来的公式:
    线程数 = [(线程等待时间 + 线程 CPU 时间) / 线程 CPU 时间] × CPU 数量
    当然还是不要“本本主义”,需要实际去做性能测试,选择合适的线程数量。
  2. 如何发现瓶颈
    JProfiler 和 Yourkit 这两个工具,它们可以列出整个请求中每个函数的 CPU 执行时间,或者使用jstack 定时地打印调用栈。
  3. 如何优化
    1.减少编码
    拿java举例,就是减少把字符编译成字节的过程,因为比较耗时
    举例:
    网页输出是可以直接进行流输出的,即用 resp.getOutputStream() 函数写数据,把一些静态的数据提前转化成字节,等到真正往外写的时候再直接用 OutputStream() 函数写,就可以减少静态数据的编码转换。
    2.减少序列化
    把关联性强的应用进行合并部署,放到同一个tomcat容器中,不走本机的socket
    3.Java优化
    把大量的请求和数据从nginx或者Web代理容器(Varnish、Squid)中返回;
    直接写servlet,避免使用传统的框架
    直接输出流数据 resp.getOutputStream()
    4.并发读缓存
    利用一致性hash及案例集中式缓存