见招拆招:秒杀系统的四大招数

面对海量的请求,我们可以做什么?

高并发请求的四大应对招数:扩容、静态化、限流,以及必杀技“有损服务”。

1 招数一:扩容

加机器,这是最简单的方法,通过增加服务器池的整体承载量来抗峰值,但是这样会造成资源的浪费,而且伸缩性较差,不能够及时的对突然到来的海量流量做出应变。

比如说,我们原有的服务器池可以承载 10,000 的 QPS,但是平常我们的访问量只有不到 200 QPS,这就会造成巨大的资源浪费;

但是如果我们把服务器数量降下去,承载量变为 500 QPS,突然来了 10,000 条请求,这时动态增加机器数量是来不及的,就会出现服务宕机等重大事故。

那怎么样的扩容才是正确的姿势呢?有这么一种参考方案:

通过消息队列接受所有的请求,消息队列反馈一个消费者不足的状态,然后通过状态监控服务向运维服务器发出警告,运维服务器进行动态扩容,开启新的的业务服务器来消费消息队列中的请求。

2 招数二:静态化

首先是将所有的静态资源转移到静态资源服务器或者 CDN 上,避免业务服务器分发静态资源;

其次尽可能的减少前后端交互,将所有可缓存、静态化的数据完全静态化(比如查询商品信息的接口数据,这个数据是可以做短时效缓存的),并由业务服务器主动推送到 CDN 等静态资源服务器上,设置较短的更新间隔(比如每秒更新一次静态资源,这样业务服务器的 QPS 就变为了常量级别),从而极大的减少业务服务器的负载。

记住一点,静态资源不仅仅是图片,甚至可以是 JSON/XML 数据。

3 招数三:限流

限流策略可以从两端进行设计,一是前端行为限流,二是后端接口限流。

3.1 前端行为限流

顾名思义,前端行为限流就是通过用户在前端的行为进行限流,目的是尽可能的避免用户的无效点击。

比如说,在活动开始之前,秒杀按钮应该是不可点击的状态,避免用户无聊在秒杀活动开始之前发送若干无效的请求;

再就是秒杀过程中,用户可能已经发送了请求,但是服务器的响应需要一段时间,那么我们应当禁止用户在这段时间之内再次点击抢购按钮发送无效的抢购请求。

通过上述两种限流方式,可以极大程度的限制前端发送过来的无效请求。

3.2 后端接口限流

前后端设计中有一条准则:永远也不要相信用户传来的数据。

后端接口限流主要是针对恶意请求的限流,在大型电商系统中通常会结合风控系统进行协同工作。通常会根据用户的唯一 ID 以及 IP 来进行限流,限制每个用户或 IP 在规定时间内只能访问多少次,超出限制就拒绝服务或拉入黑名单。

接口限流可以非常有效的拦截恶意请求,但是对于分布式恶意请求(比如肉鸡炸弹)就需要更高级的风控系统来进行协同合作了。

4 必杀技:有损服务

最后一招,在接近前端池承载能力的水位上限的时候,随机拒绝部分请求来保护活动整体的可用性。

这种招数听上去怪怪的,但是确实是非常有效的一招。虽然丢弃了部分请求,但是保证了服务器的可用性,保持了业务的持续运作。

至于被丢弃的请求嘛,就当运气不好没抢到好了:)。

IInfinity

IInfinity

大道虽简,知易行难。
CN