保障系统高可用性 之 限流(一)

1,305 阅读6分钟

我们经常可以看到各大云服务厂商号称自己的服务五个九,这里的五个九指的就是系统服务时间占整体时间的99.999%,按照一年来算的话,系统宕机时间必须小于5分16秒。对于某些核心系统而言,系统服务一旦宕机会给很多下游服务和客户带来影响,所以一个可靠的系统必须具备高可用性。今天主要谈谈和系统开发相关的--限流。

1.引言

首先,借用比较火的微服务中的概念,级联故障(Cascading failure),来说明限流的重要性。级联故障在计算机系统中,可以描述成,某个服务节点失败,而导致请求重新分配至其他服务节点,导致其他服务节点过载而相继失效的问题。

下图是wiki上,说明级联故障的图示。

1.1 避免资源消耗殆尽

我们如果把系统服务看做某种资源,比如掘金首页的信息流文章,由于服务器资源有限,所以很多情况下,我们做限流的主要目的是,为了能够尽可能地保证服务资源不被消耗殆尽,避免导致上面讲的级联故障的问题。

1.2 服务资源管理

有些时候,由于服务产品等级不同,可能需要对用户等级进行区分,进而控制各等级用户使用资源的层级,这也是限流的用武之地。典型的比如Saas多租户,对于普通客户来说,可能只能使用共享的服务资源,而对于付费购买的客户,可能会单独分配服务资源,这两者就需要使用限流进行资源分配。

1.3 避免开销成本

随着Serveless技术成熟,越来越多的产品迁移至无服务器架构上,这样做的优点很多,动态扩容可以合理利用服务器资源,避免过度浪费。然而,在不同的场景下,都可能会有突发流量的问题出现,比如某个点流量翻倍,但是持续时间很短,这个时候是否采用动态扩容就会造成服务成本的上涨,而限流可能是个更好的办法。

2.限流手段

相应地,限流方法也多种多样,针对不同的场景,其要求也不尽相同,而了解这些手段,可以方便后续的系统设计和决策。

2.1 非限流措施

通常情况下,对于系统设计而言,我们需要有个兜底的方案,也就是说即使限流手段都失败的情况下,系统依然能够将正常的错误系统和提示反馈出来。常见的系统过载时,系统服务可以设置固定超时时间服务熔断来保证服务调用方获得服务异常原因(理论上讲,熔断属于限流的一种)。

2.2 服务降级

针对某些重要的服务,往往在面对大量负载时,需要将部分请求进行降级处理,因为某些情况下,数据库或计算资源是有限的,而单次请求计算又比较昂贵,这时就可以通过服务降级的方式,而降低系统的整体负载,比如:

  1. 如果服务返回的信息中包含大量内容,可以只将关键信息返回,其他信息不进行获取。
  2. 使用缓存结果替代真实结果,可能会出现数据的不一致性,但是满足了服务的高可用性,短暂情况下是可以允许的。
  3. 甚至直接返回固定的结果,这个策略反而很多时候简单粗暴,可以大大降低系统的复杂度。

2.3 延迟处理

在某些内部系统中,部分请求的实时性不高,或者不需要返回结果的情况下,系统面对高负载时,可以进行延迟处理,也是变相地降低某个时间段内系统处理的频率。简单的做法,可以是延迟一段时间进行处理;更多的时候,需要使用消息系统做任务的转存,方便任务处理失败或超时情况下的重试。

2.4 服务限流

对于大部分场景而言,可能需要我们对服务的请求负载进行限流处理,保证系统负载平稳,正常。常见的限流方法如下:

  1. 计数器方式,其主要想法是通过维护计数,来保证系统运行时,不会出现过多的服务请求。
  2. 漏桶算法,漏桶算法相比计数器方式而言,增加了匀速处理流程,保证系统处理速度在过载情况下,仍然能够匀速进行。
  3. 令牌桶算法,令牌桶算法,则是将服务请求抽象为资源,通过系统生成令牌的方式,保证系统在某个时刻处理固定的令牌数请求,达到保护系统的目的。
  4. 固定时间窗口方式,该方法是通过指定某个固定的时间窗口内,系统可以处理的固定请求数来达到保护系统的目的。
  5. 滑动窗口方式,该方法可以解决固定时间窗口的缺陷,在固定时间窗口中,存在突发流量不能平滑处理的问题,比如,固定时间窗口是一分钟最多处理一千次请求,而在后续的一秒钟内,系统接收到两千次请求,就会出现后续的一千次请求需要等待到下一个时间窗口上去。而滑动窗口通过将窗口分成若干小间隔,保证每个小间隔都能处理适当的请求,可以让系统在面对突发的流量下,负载更加平滑。
  6. 动态限流,该类限流主要的优点在于,可以根据系统运行期状态,动态调整限流规则。有些类似TCP拥堵算法,通过算法流程进行限流控制;有些则参考历史负载情况,对于短期负载进行智能适应。

上述具体算法详解与实现过程,详见下篇文章《保障系统高可用性 之 限流(二)》

问题

  1. 常说“不要过早优化”,而限流等手段却是需要在系统设计时就要考虑的,这两者的关系如何权衡?
  2. 不同的限流算法,对系统负载的影响如何,如何根据系统场景来选择合适的限流算法?

欢迎各位拍砖交流,讲讲自己的看法,互相学习。