秒杀场景的挑战和解决方案

挑战

秒杀是商品促销的常用手段,该用户场景的特点就是集中大量的下单,同时由于下单流程的特殊性,扣库存,下订单都要求很高的数据一致性,不能出现超卖错卖,所以下单请求其实是存在单点问题的(主要是数据库的处理速度不够快),不能做到平行扩展,在单位时间内对同一商品的下单请求存在上限。所以问题的核心就在于如何限制单位时间内用户的下单请求数量,也就是限流,同时又不能伤害用户的体验。
面对秒杀场景,有很多相关的技术分析,大多都能分析到某一些技术优化点。其实这就是一些最佳实践。但是从更高一点的层次上来看,所有的优化方案(不仅仅是针对秒杀),无外乎是从产品设计,前端,后端这几个点入手。毕竟整个订单的生命周期就包括这几个部分。

产品设计

1,秒杀商品设置单独的页面
2,秒杀商品需要预约,甚至必须交定金,这极大的减少了无效请求
3,秒杀商品的抢购和下单是分开的,可以先提示抢购已成功,正在生成订单。这是因为扣库存是一个相对快的操作,而下订单是一个相对慢的操作,所以这是一个技术限制导致的流程变化
4,秒杀商品需要有倒计时,指定时间才可以下单
5,秒杀商品的特殊逻辑,比如弹幕,或者展示一些某某某购买成功等促销逻辑

前端设计

1,提前过滤无效用户,比如没有预约或者没有登录或者黑名单的用户。

2,假请求。虽然用户点了抢购按钮,立即调到抢购中的页面,但是实际请求会在随机延后几秒才发送。

3,重试。当请求返回409(too many requests)或者超时的时候,应该延后再重试。

4,前后端分离,前端所有资源都可以通过cdn分发,并且针对秒杀场景做页面精简,比如去除广告模块等。

后端设计

1,网关限流,可以提前通过压力测试发现抢购接口的qps,通过设置相应的url,用商品id做hash key,在nginx配置hash限流。nginx的数量一般不会变,所以每个nginx的限流数量等于总数量÷nginx的数量

2,缓存,每次扣存储先检查redis里面的库存数量,扣库存后,更新redis

3,设置合理的超时间隔,不管是访问redis还是mysql,都应该快,不应该长时间导致请求累积导致雪崩效应。

4,配合产品做抢购(扣库存)和下单的异步分离。

部署隔离

这个不是什么优化方案,但是很重要。因为秒杀长长带来系统瘫痪,所以秒杀业务和正常业务要求部署隔离。存储缓存api都应该单独部署。

你可能感兴趣的:(笔记)