弹力设计篇之“限流设计”

保护系统不会在过载的情况下出问题

限流的策略

限流的目的是通过对并发访问进行限速,相关的策略一般是,一旦达到限制的速率,那么就会触发相应

的限流行为

限流之后触发的行为有:

1.拒绝

2.降级

3.特权处理

4.延迟处理

5.弹性伸缩,这里如果流量过大,服务抗不住了,这时候就需要去加机器,需要一个自动化的发布、部署和

服务注册的运维系统

限流的方式

计数器

最简单粗暴的

队列方式

但这种方式process得用 pull的方式,不然队列过长,没满,processor就先挂掉了

queue的配置是一个学问来着

漏斗算法 Leaky Bucket

水溢出了就触发限流,这种算法下 处理请求是非常平滑的

实现一般都是通过一个队列来实现,请求多了,队列开始积压请求,超过长度就拒绝请求。

tcp的流量控制就是这么来的,当请求过多时,会有一个sync backlog队列来缓冲请求,滑动

窗口其实也是

代码:

1

令牌桶算法 Token Bucket

这个算法相当于有个中间人,我们请求要过得去,得去这个中间人拿Token。然后会在一个桶内按照一定的

速率放入一些 token。这种设计可以在流量少时攒钱,流量大时快速处理

如果 Processor 是瓶颈(慢的业务逻辑处理器),算法对总吞吐量影响不大,因为 Processor 才是限

制。

如果 Processor 很快(像 Nginx),算法就决定了请求转发节奏:漏斗稳、令牌桶能爆发。

代码:

1

基于响应时间的动态限流

以上算法有个不好的点,就是得去设置一个上限值,这个一般都是我们通过压测得到

虽然我们网关可以做到接口级别的限流,但为每一个api去配置,管理起来其实是很麻烦的

而且,现在的服务都是能自动化伸缩的,不同大小的集群的性能也不一样,所以,在自动化伸缩的情况下,我们要动态地调整限流的阈值,这点太难做到了

那有没有一种能自动根据系统情况进行限流的算法呢

:::color4
这种方式,不再设定一个特定的流控值,而是能够动态地感知系统的压力来自动化地限流

这方面设计的典范是 TCP 协议的拥塞控制的算法

它的是通过RTT 来探测网络的延时和性能,从而确定滑动窗口的大小,我们完全可以参考它的设计

结合计网中学到tcp的一些知识,当时一开始想到就是

:::

系统自适应限流

基于错误率,且采样基数要大

限流设计要点

限流目的:

向用户承弱SLA,高并发下保证可用性

保护服务不崩

在多租户的模式下,保证重要的租户仍然可用

节约成本,我们不会为了一个不常见的尖峰来把我们的系统扩容到最大的尺寸

网关TODO:

0.手动开关

1.head上加上标识,让后端知道发生了限流,后端可以根据这个标识决定是否做降级

2.对于监控,监控应该立马感知到,运维能持续跟进

3.网关性能必须好

荣耀:APIX单机 -> 分布式限流一步步 优化方案

单机限流

第一阶段:

只是单机,如果后端网关节点是动态变化的,就不符合需求

第二阶段

我们可以引入一个第三方比如 配置中心ETCD,NACOS,来管理我们的限流总量

性能优化:

  1. 开一个特权进程来进行ETCD从拉取网关信息,同时避免APISIX本身的开销
  2. 特权进程写入共享内存,进程间共享网关信息数据

第三阶段

APISIX 在荣耀海量业务下的网关实践 | Apache APISIX® – Cloud-Native API Gateway and AI Gateway

分布式限流

在应用开源分布式限流方案时,我们遇到了以下关键问题:

  1. Redis 性能瓶颈:单 key 限流场景下,当限流规则针对整个路由而非路由特征时,Redis 的 key 会过于单一,导致所有请求集中到同一个 Redis 分片,无法通过横向扩容实现负载均衡。
  2. 网络性能消耗:频繁的 Redis 请求导致网关节点 CPU 使用率上升 50%+。
  3. 请求时延增加:开源分布式限流方案需先访问 Redis 完成计数,再将请求转发至上游,导致业务请求时延增加 2-3 毫秒。

Click to Preview

优化方案

为解决上述问题,我们设计了以下优化方案:

Click to Preview

  1. 引入本地计数缓存:

a. 本地计数机制:请求到达时,首先在本地计数缓存中扣除一个计数。只要计数未降至 0,请求即被放通。

b. 异步同步机制:本地计数通过异步方式定期与 Redis 同步,统计两次同步期间的请求量,并在 Redis 中扣除相应的计数。同步完成后,Redis 的计数覆盖本地缓存,确保分布式限流的一致性。

  1. 误差控制:通过合理的公式计算和参数配置,将误差率控制在 3%-4% 的范围内,确保限流精度满足业务需求。

适用场景

  • 高 QPS 应用:该方案适用于 QPS 较大的应用,能够显著降低 Redis 的性能瓶颈和网络开销。
  • 低 QPS 应用:对于 QPS 较低(如几百 QPS)的应用,现有的分布式限流方案已基本满足需求,无需额外优化。