如何设计一个秒杀服务

什么是秒杀?

大促降价
在特殊时间点(如京东618,天猫双11)进行的大量商品促销活动,引发大量用户集中访问和下单导致系统遭到巨大压力的考验。

传统业务架构

传统业务架构图

秒杀的特点和引发的风险

  1. 短时间大量用户访问网站,网站系统的读压力骤然升高,有挂掉的风险。
  2. 商品数量有限,而大量用户下单,商品存在超卖风险。
  3. 在大量用户集中访问的前提下需要保证系统的性能,即用户访问网站也需要较低的延时才能得到较好的用户体验。
  4. 对现有业务产生冲击,秒杀服务不应干扰其他业务正常进行。

针对秒杀特点的服务的优化思路

  1. 针对网站读压力很高的特点,可以加缓存解决。
  2. 针对超卖风险,可以让库存扣减串行化。
  3. 针对用户体验,在系统性能不足情况下打开降级开关,缓存整个页面,页面库存数显示为“有货”。

秒杀架构下各个层的优化点

APP端优化点

  1. 活动开始前提前下载秒杀活动需要的静态资源,如html css 图片。
  2. 针对秒杀活动提交订单后提交按钮置灰一段时间,防止用户不断点击尝试提交订单增加系统压力。
  3. 下单按钮的URL动态化,防止活动开始前就能抢购。

网站优化点

  1. 浏览器加缓存
  2. 其他同APP第二、三、四点

网络优化点

  1. 网站域名增加多DNS解析,让用户访问离自己最近的机房。防止全国用户单点访问。
    用户访问
    例如用户访问www.taobao.com,淘宝会通过DNS解析的手段将你的请求引导到最近的机房。
  2. 网站动态资源,如商品图片 提前存入和预热CDN以减轻源服务器带宽压力。
  3. 使用P2P技术

Nginx优化点

  1. 由于商品降价促销势必引来爬虫和灰黑产的大量访问,可由Nginx识别该类请求,做IP deny。
  2. nginx开启短时间缓存机制,匹配到相同URL可直接返回。
  3. 根据商品SKUID等信息在nginx内使用lua脚本组装redis key访问redis集群,若命中缓存则直接返回。
  4. 可使用SSI技术动态拼接HTML内容返回。
  5. 前端请求合并,一次返回页面全部数据,减少网络IO次数。

商城服务优化点

  1. 热点数据使用redis集群缓存。
  2. 秒杀商品数量可提前加入redis,下单做串行化。可如下设计
    下单请求处理
  3. 若能预估访问量和商品库存的比例关系,可直接丢弃部分请求。
  4. 商城服务可以考虑拆分成商品服务、订单服务、下单服务、库存服务等做针对性优化。
  5. 可以水平扩展压力过大的服务,如现在10台库存服务器顶不住可增加到20台。
  6. 可考虑在服务内使用MapDB、EhCache等内存数据库短时间缓存样板数据。

DB优化点

  1. 可作读写分离,读请求访问从库,变相提升写性能。
  2. 垂直拆分,将订单、商品、库存等信息单独存库,压力大的机器可弹性扩展。
  3. 数据异构,将商品信息按多维度存储,订单信息也可按多维度存储。

其他优化点

  1. 可引入MQ平滑处理瞬时大量请求,当MQ入队数量达到商品库存数时后续下单请求可直接返回失败。
  2. 当系统承载压力达到极限时可降级处理访问请求,比如请求商品详情页返回托底页面,以免显示404等不友好信息。
  3. 可引入F5等四层负载均衡器,最新版本的nginx现也支持四层负载均衡。

改进后的架构图

改进后的架构图
其他优化改进点欢迎各路大神补充~

猜你喜欢

转载自blog.csdn.net/u011580177/article/details/106180647