什么是秒杀?
在特殊时间点(如京东618,天猫双11)进行的大量商品促销活动,引发大量用户集中访问和下单导致系统遭到巨大压力的考验。
传统业务架构
秒杀的特点和引发的风险
- 短时间大量用户访问网站,网站系统的读压力骤然升高,有挂掉的风险。
- 商品数量有限,而大量用户下单,商品存在超卖风险。
- 在大量用户集中访问的前提下需要保证系统的性能,即用户访问网站也需要较低的延时才能得到较好的用户体验。
- 对现有业务产生冲击,秒杀服务不应干扰其他业务正常进行。
针对秒杀特点的服务的优化思路
- 针对网站读压力很高的特点,可以加缓存解决。
- 针对超卖风险,可以让库存扣减串行化。
- 针对用户体验,在系统性能不足情况下打开降级开关,缓存整个页面,页面库存数显示为“有货”。
秒杀架构下各个层的优化点
APP端优化点
- 活动开始前提前下载秒杀活动需要的静态资源,如html css 图片。
- 针对秒杀活动提交订单后提交按钮置灰一段时间,防止用户不断点击尝试提交订单增加系统压力。
- 下单按钮的URL动态化,防止活动开始前就能抢购。
网站优化点
- 浏览器加缓存
- 其他同APP第二、三、四点
网络优化点
- 网站域名增加多DNS解析,让用户访问离自己最近的机房。防止全国用户单点访问。
例如用户访问www.taobao.com,淘宝会通过DNS解析的手段将你的请求引导到最近的机房。 - 网站动态资源,如商品图片 提前存入和预热CDN以减轻源服务器带宽压力。
- 使用P2P技术
Nginx优化点
- 由于商品降价促销势必引来爬虫和灰黑产的大量访问,可由Nginx识别该类请求,做IP deny。
- nginx开启短时间缓存机制,匹配到相同URL可直接返回。
- 根据商品SKUID等信息在nginx内使用lua脚本组装redis key访问redis集群,若命中缓存则直接返回。
- 可使用SSI技术动态拼接HTML内容返回。
- 前端请求合并,一次返回页面全部数据,减少网络IO次数。
商城服务优化点
- 热点数据使用redis集群缓存。
- 秒杀商品数量可提前加入redis,下单做串行化。可如下设计
- 若能预估访问量和商品库存的比例关系,可直接丢弃部分请求。
- 商城服务可以考虑拆分成商品服务、订单服务、下单服务、库存服务等做针对性优化。
- 可以水平扩展压力过大的服务,如现在10台库存服务器顶不住可增加到20台。
- 可考虑在服务内使用MapDB、EhCache等内存数据库短时间缓存样板数据。
DB优化点
- 可作读写分离,读请求访问从库,变相提升写性能。
- 垂直拆分,将订单、商品、库存等信息单独存库,压力大的机器可弹性扩展。
- 数据异构,将商品信息按多维度存储,订单信息也可按多维度存储。
其他优化点
- 可引入MQ平滑处理瞬时大量请求,当MQ入队数量达到商品库存数时后续下单请求可直接返回失败。
- 当系统承载压力达到极限时可降级处理访问请求,比如请求商品详情页返回托底页面,以免显示404等不友好信息。
- 可引入F5等四层负载均衡器,最新版本的nginx现也支持四层负载均衡。
改进后的架构图
其他优化改进点欢迎各路大神补充~