首页 > 数据库 >gateway结合redis做限流

gateway结合redis做限流

时间:2023-06-09 17:24:51浏览次数:54  
标签:令牌 请求 redis public 算法 限流 gateway

本篇是针对已经实现了gateway基础功能的项目,如果需要实现基础功能可以参考 https://www.cnblogs.com/cbzhl/p/17467019.html

针对于并发量比较高的时候,如果不针对对应的服务做限流操作,可能造成服务器压力过大,宕机等情况,为此出现了多种限流的方式:

  • 计数器算法(Counter)。 --设计一个计数器,比如一个全局的变量,每次请求后+1,并且在限定时间内比如一分钟,将计数器重置一次。当每次请求时查看计数器是否已经为临界值了,是就限流。但是这个有个缺点就是比如在55秒前没有请求,在55-70秒时有20000次请求,而计数器的临界值则是10000,此时的在60秒时清空了一次,这20000次的请求也是可以进来的。
  • 漏桶算法(Leaky Bucket)。--就是所有的请求都放到gateway中,然后再去一个一个分发下去到对应的服务,这样做的缺点就是在大量数据的请求下可能gateway根本无法承受,而下游的服务依然在空闲当中或是毫无压力。
  • 令牌桶算法(Token Bucket)。--设计一定数量的令牌,每次请求都会取一个令牌,并且令牌桶会根据规则自动生成令牌。大量请求过来时超过了限定的值,桶里的令牌瞬间被抢空,剩下没有拿到令牌的请求将会失败,并且桶中的令牌一直是有序增加的剩下的请求也能抢到。目前这是一种最优的解决方案。

Gateway的令牌桶算法实现:

Gateway中的限流算法就是采用了令牌桶算法,支持三种令牌桶算法:基于URI限流、基于请求参数限流、基于IP限流。

1.引入依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--redis支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

2.添加配置信息

 

server:
  port: 9003
eureka:
  client:
    fetch-registry: true # 从 eureka 服务端获取注册信息
    register-with-eureka: true # 将自身注册到 eureka 服务端
    service-url:
      defaultZone: http://localhost:9000/eureka
  instance:
    prefer-ip-address: true # 开启采用 IP 注册形式
spring:
  application:
    name: flowershop-gateway
  cloud:
    gateway:
      routes:
        - id: gateway-flower #路由id,唯一
          uri: lb://flowershop-common #路由地址,针对哪个服务的路由
          predicates: #断言
            - Path=/** 
          filters:
              # 指定限流过滤器
            - name: RequestRateLimiter
              args:
                  # 基于令牌桶算法,生成令牌的速率
                redis-rate-limiter.replenishRate: 1
                  # 令牌桶的最大容量
                redis-rate-limiter.burstCapacity: 1
                  # 指定生成令牌的算法解析策略,这里是使用了SpEL表达式,获取寻找名字是 keyResolver 的bean对象
                key-resolver: "#{@keyResolver}"
  redis:
    host: 192.168.3.52
    database: 0
    port: 6379
    password:
    jedis:
      pool:
        max-idle: 100
        max-wait:
        min-idle: 5
    timeout: 500

3.令牌算法

Gateway中有多种限流策略,通过URI进行限流、通过请求参数限流、通过IP地址限流,但是我们只可以去实现其中一种。可以去实现 KeyResolver 接口

可以有多种方式实现:在启动类中实现、使用配置类实现

这里我们使用配置类

/**
 * @Description 令牌桶算法中,令牌的生成算法
 * @Author zhl
 * @Date 2023/6/9 11:22
 */
@Configuration
public class KeyResolverConfiguration{
    @Bean
    public KeyResolver keyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                // 这里根据请求【URI】进行限流
                return Mono.just(exchange.getRequest().getPath().toString());
            }
        };
    }


//    @Bean
//    public KeyResolver keyResolver() {
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                // 这里根据请求【请求参数username】进行限流
//                return Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));
//            }
//        };
//    }
//
//    @Bean
//    public KeyResolver keyResolver() {
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                // 这里根据请求【IP地址】进行限流
//                return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
//            }
//        };
}

4.运行测试。

利用postman的并发测试

创建一个文件夹

 新建请求并保存到这个文件夹中

点击文件夹的三个点(或者是三角符号,因为版本不同)。选择Run collection

 查看运行结果,发现很多的429失败,这个就表示被限流了,并且偶尔也会蹦出一些200的成功,进一步证明了上述说的令牌桶会自增的机制

 

标签:令牌,请求,redis,public,算法,限流,gateway
From: https://www.cnblogs.com/cbzhl/p/17469376.html

相关文章

  • 【缓存】J2Cache —— 基于内存和 Redis 的两级 Java 缓存框架的使用方法
    本文目录一、J2Cache简介二、数据读取三、使用方法及实际示例3.1引用Maven3.2准备配置3.3编写代码3.3.1Demo示例3.3.2实际案例四、常见问题4.1J2Cache的使用场景是什么?4.2为什么不能在程序中设置缓存的有效期4.3如何使用memcached作为二级缓存4.4使用何种Redis的存......
  • 关于redis在我们数据平台升级版本时出现的问题
    redis启动原来我们是用写死的代码后来统一使用了启动脚本这就导致了redis存储的问题 我们知道,redis在默认情况(appendonlyno)下是使用快照存储,然而在写死的代码中,快照存储的位置是rootPath(我们的数据产品的根路径)大概更新了三个版本之后,bat脚本启动的位置是根路径\redis路径......
  • Linux安装Redis
    1、系统环境[root@localhost~]#cat/etc/redhat-release2、安装依赖yum -y installgccgcc-c++pcrepcre-develzlibzlib-developensslopenssl-devel3将redis-3.2.1.tar.gz安装包上传到服务器的/usr/local/目录下3.1解压redis压缩包[root@localhostlocal]#tar-xvfre......
  • Using Redis Cache for session data storage in ASP.NET Core
    reference: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-6.0Postedon:11-12-2017TweetWhenyourunanappindevelopmentortesting,itcanbeokayforsessiondatatobelostduringapprestarts.However,in......
  • 如何正确使用redis实现分布式锁?
    分布式锁三种实现方式:数据库乐观锁基于redis的分布式锁基于zookeeper的分布式锁为了保证分布式锁的高可用,我们至少要确保所得实现同时满足一下几个条件:   互斥性,即就是在任意时刻只有一个客户端能持有锁   不会发生死锁,即就是说计算有一个客户端持有锁期间崩了但是锁没有......
  • 源码安装redis-migrate-tool(redis迁移工具)部署安装
    源码安装redis-migrate-toolredis-migrate-toolunzipredis-migrate-tool-master.zipcdredis-migrate-tool-masteryum-yinstallautomakelibtoolautoconfbzip2autoreconf-fvi./configuremake./src/redis-migrate-toolrmt.conf配置项修改[source]typ......
  • RedisTemplate常用方法总结
    很多公司都将redisTemplate进行了封装,封装成业务所需要的RedisUtil工具类方便进行调用,本篇文章总结了redisTemplate常用的一些方法。Redis常用的数据类型:•String•Hash•List•Set•zSet•SortedsetString类型判断是否有key所对应的值,有则返回true,没有则返回false......
  • 关联:Redis I/O模式
    Redis使用的是I/O多路复用首先,Redis是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以I/O操作在一般情况下往往不能直接返回,这会导致某一文件的I/O阻塞导致整个进程无法对其它客户提供服务,而I/O多路复用就是为了解决这......
  • Redis 面试题
    1.Redis是什么?Redis是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景。2.Redis有哪些数据类型?5种基础数据结构:String(字符串)、List(列表)、Set(集合)、Hash(哈希)、Zset(有序集合)。3种特殊数据结构:HyperLogLogs(......
  • redis 安装fatal error: jemalloc/jemalloc.h: No such file or directory 错误
    转自;https://www.cnblogs.com/oxspirt/p/11392437.html 问题现象: 我第一次安装redis时,没有安装gcc,报错了,然后安装好gcc,后再次执行make命令,安装redis就出现了如上的错误 网上错误解决办法网上大部分解决办法都是错误的,如下文:(错误解决办法)makeMALLOC=libc正确解决......