高并发之限流算法

高并发之限流算法

在我们的实际的生产当中存在这样的业务场景:短时间有大量的请求涌入造成了系统的崩溃。针对这种问题我们会采用一种服务降级的方式来保证核心服务可以正常运行。

一般来说服务降级分为两种:

  • 故障降级:当发生网络故障或者RPC服务返回异常,这种情况我们通常采用关联fallback方法,为客户端设置兜底数据,从而避免造成服务依赖的“雪崩”现象。
  • 限流降级:无论系统运行在什么样的服务器,它都会有一定的流量带宽极限,我们可以采用设置请求阈值的方式来避免过多的请求涌入从而造成系统的崩溃。

不同的RPC框架都有着不同的配置故障降级的方式,故而我们这里注重讲解一下限流降级这种方式。
我们常见的限流算法有:漏桶算法、令牌桶算法和滑动窗口算法

漏桶算法

nginx的limit_conn_zone模块底层就是漏桶算法,它的特点是:

  • 它可以简单的比作就是注水漏水过程,往桶中以一定速率流出水,以任意速率流入水,当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。
  • 它能够强行限制数据的传输速率,但是由于流速是恒定的,对突发特性的流量是无法处理的 。
    在这里插入图片描述

令牌桶算法

能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。
令牌桶算法是最常用的限流算法,通常配合redis来实现, 具体参考我的博客:redis令牌桶限流

它的工作原理可以简单概括为:

  1. 所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;

  2. 根据限流大小,设置按照一定的速率往桶里添加令牌;

  3. 桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;

  4. 请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;

  5. 令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流;

在这里插入图片描述

滑动窗口算法

我们熟知的Sentinel高可用流量控制框架采用的就是滑动窗口的方式进行流量控制。

  • 它将时间窗口划分为更小的时间片段,每过一个时间片段,我们的时间窗口就会往右滑动一格,每个时间片段都有独立的计数器。
  • 我们在计算整个时间窗口内的请求总数时会累加所有的时间片段内的计数器。
  • 时间窗口划分的越细,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

简单举个例子:我们设置一个窗口有两个方案

  • 设置 A :10s 100条请求
  • 设置 B :1s 10条请求

相对而言设置B的系统相对而言更加稳定。

在这里插入图片描述

总得来说:

  • 令牌桶算法:能够保证自身系统的流量均匀;
  • 漏桶算法:保证被调用系统(目标系统)流量均匀。
  • 实际的生产中通常采用 漏桶算法+令牌桶算法的方式来对网络流量进行高效地控制。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40990818/article/details/108190826