Redis的4种分布式限流算法

限流

服务系统流量多,的确是一件好事,但是如果过载,把系统打挂了,那大家都要吃席了。

所以,在各种大促活动之前,要对系统进行压测,评估整个系统的峰值QPS,要做一些限流的设置,超过一定阈值,就拒绝处理或者延后处理,避免把系统打挂的情况出现。

限流和熔断有什么区别?

限流发生在流量进来之前,超过的流量进行限制。

熔断是一种应对故障的机制,发生在流量进来之后,如果系统发生故障或者异常,熔断会自动切断请求,防止故障进一步扩展,导致服务雪崩。

限流和削峰有什么区别?

削峰是对流量的平滑处理,通过缓慢地增加请求的处理速率来避免系统瞬时过载。

削峰大概就是水库,把流量储存起来,慢慢流,限流大概就是闸口,拒绝超出的流量。

限流的通用流程

那么具体限流怎么实现呢?可以概括为以下几个步骤:

限流通用流程

  1. 统计请求流量:记录请求的数量或速率,可以通过计数器、滑动窗口等方式进行统计。

  2. 判断是否超过限制:根据设定的限制条件,判断当前请求流量是否超过限制。

  3. 执行限流策略:如果请求流量超过限制,执行限流策略,如拒绝请求、延迟处理、返回错误信息等。

  4. 更新统计信息:根据请求的处理结果,更新统计信息,如增加计数器的值、更新滑动窗口的数据等。

  5. 重复执行以上步骤:不断地统计请求流量、判断是否超过限制、执行限流策略、更新统计信息

需要注意的是,具体的限流算法实现可能会根据不同的场景和需求进行调整和优化,比如使用令牌桶算法、漏桶算法等。

单机限流和分布式限流

我们注意到,在限流的通用流程里,需要统计请求量、更新统计量,那么这个请求量的统计和更新就必须维护在一个存储里。

假如只是一个单机版的环境,那就很好办了,直接储存到本地。

单机vs集群

但是一般来讲,我们的服务都是集群部署的,如何来实现多台机器之间整体的限流呢?

这时候就可以把我们的统计信息放到Tair或Redis等分布式的K-V存储中。

四种限流算法与分布式实现

接下来,我们开始实现一些常见的限流算法,这里使用Redis作为分布式存储,Redis不用多说了吧,最流行的分布式缓存DB;Redission作为Redis客户端,Redission单纯只是用来做分布式锁,有些”屈才“,其实用来作为Redis的客户端也非常好用。

五种限流算法分布式实现

在开始之前,我们先简单准备一下环境,Redis安装和项目创建就不多说了。

  • 添加依赖

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.2</version>
        </dependency>
  • 用单例模式获取RedissonClient,这里就不注册成bean了,跑单测太慢

public class RedissonConfig {

    private static final String REDIS_ADDRESS = "redis://127.0.0.1:6379";

    private static volatile  RedissonClient redissonClient;

   public static RedissonClient getInstance(){
        if (redissonClient==null){
            synchronized (RedissonConfig.class){
                if (redissonClient==null){
                    Config config = new Config();
                    config.useSingleServer().setAddress(REDIS_ADDRESS);
                    redissonClient = Redisson.create(config);
                    return redissonClient;
                }
            }
        }
        return redissonClient;
    }
}

1、固定窗口限流算法

算法原理

固定窗口算法,很多参考资料也称之为计数器算法,当然我个人理解,计数器算法是固定窗口算法的一种特例,当然我们不纠结那么多。

固定窗口算法,是一种比较简单的限流算法,它把时间划分为固定的时间窗口,每个窗口内允许的请求次数设置限制。如果在一个时间窗口内,请求次数超过了上限,那么就会触发限流。

猜你喜欢

转载自blog.csdn.net/WXF_Sir/article/details/131701417