gateway基于redis做限流处理


前言

限流的意义

限流是针对于并发量比较高的时候,如果不针对对应的服务做限流操作,可能造成服务器压力过大,宕机等情况.


一、如何限流?

限流的方式:

  • 计数器算法(Counter)

–设计一个计数器,比如一个全局的变量,每次请求后+1,并且在限定时间内比如一分钟,将计数器重置一次。当每次请求时查看计数器是否已经为临界值了,是就限流。但是这个有个缺点就是比如在55秒前没有请求,在55-70秒时有20000次请求,而计数器的临界值则是10000,此时的在60秒时清空了一次,这20000次的请求也是可以进来的。

  • 漏桶算法(Leaky Bucket)

–就是所有的请求都放到gateway中,然后再去一个一个分发下去到对应的服务,这样做的缺点就是在大量数据的请求下可能gateway根本无法承受,而下游的服务依然在空闲当中或是毫无压力。

  • 令牌桶算法(Token Bucket)

–设计一定数量的令牌,每次请求都会取一个令牌,并且令牌桶会根据规则自动生成令牌。大量请求过来时超过了限定的值,桶里的令牌瞬间被抢空,剩下没有拿到令牌的请求将会失败,并且桶中的令牌一直是有序增加的剩下的请求也能抢到。目前这是一种最优的解决方案。

二、使用步骤

Gateway的令牌桶算法实现:

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

  • 引入依赖:
<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>
  • 添加配置信息
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
  • 令牌算法

Gateway中有多种限流策略,通过URI进行限流、通过请求参数限流、通过IP地址限流,但是我们只可以去实现其中一种。可以去实现 KeyResolver 接口
可以有多种方式实现:在启动类中实现、使用配置类实现
这里我们使用配置类

/**
 * 令牌桶算法中,令牌的生成算法
 */
@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());
//            }
//        };
}

总结

一般情况下,项目中都会用到redis作为缓存,既然这样,我们完全可以用redis做gateway限流处理,可以减少sential插件的引入以及学习成本,何不美哉~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Cloud Gateway是一个构建在Spring Framework基础上的API网关,它可以用于实现负载均衡、路由转发、限流等功能。在进行限流操作时,Spring Cloud Gateway通常会使用一种称为令牌桶(Token Bucket)的算法。 令牌桶算法是一种简单有效的限流算法,它基于一个桶(Bucket)来存放一定数量的令牌(Token)。每个令牌表示一个可以访问服务的权限,当服务需要处理请求时,必须先获取一个令牌,如果桶中没有令牌,就需要等待。 通常情况下,Spring Cloud Gateway限流功能是通过在网关层面进行处理的。当请求到达网关时,网关会先检查请求是否超过限流规定的阈值,如果超过则拒绝请求,否则继续向后传递。这个限流操作并不会涉及到线程的变化。 而关于线程变为Redis的线程,可能是指在实际运行中,为了维护令牌桶算法所需的状态信息,可以将令牌桶的相关数据存储在Redis中,这样可以实现分布式限流,保证多个网关实例之间的限流规则一致性。 具体来说,可以在网关应用中使用Redis来存储令牌桶的Token信息,并使用Redis的分布式锁来保证多个网关实例之间对令牌桶的访问的互斥性,从而实现分布式限流的效果。这样,在实际运行中,网关处理请求时会从Redis中获取令牌桶的信息,并使用令牌桶算法进行限流操作。 总之,Spring Cloud Gateway限流功能并不会导致线程的变化。但为了实现分布式限流,可以将令牌桶的相关数据存储在Redis中,从而在网关处理请求时可以从Redis中获取令牌桶的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寂寞旅行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值