开发喵星球

若依微服务限流配置(229)

限流就是限制流量。通过限流,我们可以很好地控制系统的 QPS,从而达到保护系统的目的。
常见的限流算法有:计数器算法,漏桶(Leaky Bucket)算法,令牌桶(Token Bucket)算法。

Spring Cloud Gateway官方提供了RequestRateLimiterGatewayFilterFactory过滤器工厂,使用 RedisLua脚本实现了令牌桶的方式。

1、添加依赖

在网关服务(ruoyi-gateway)的 pom.xml 文件中添加 spring-boot-starter-data-redis-reactive 依赖

<!-- spring data redis reactive 依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

2、限流规则,根据URI限流

application.yml 配置文件中,配置 Redis 连接信息,并在 spring.cloud.gateway.routes 下配置限流规则

spring:
  redis:
    host: localhost
    port: 6379
    password: 
  cloud:
    gateway:
      routes:
        # 系统模块
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量
                key-resolver: "#{@pathKeyResolver}" # 使用 SpEL 表达式按名称引用 bean

提示
StripPrefix=1配置,表示网关转发到业务模块时候会自动截取前缀。

3、编写URI限流规则配置类

编写 KeyResolverConfiguration 类,实现 pathKeyResolver() 方法,返回当前请求的 URI 路径作为限流 key

package com.ruoyi.gateway.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
 * 限流规则配置类
 */
@Configuration
public class KeyResolverConfiguration
{
    @Bean
    public KeyResolver pathKeyResolver()
    {
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

4、测试服务验证限流

启动网关服务RuoYiGatewayApplication.java和系统服务RuoYiSystemApplication.java
因为网关服务有认证鉴权,可以设置一下白名单/system/**在进行测试,多次请求会发现返回HTTP ERROR 429,同时在redis中会操作两个key,表示限流成功。

request_rate_limiter.{xxx}.timestamp
request_rate_limiter.{xxx}.tokens

其他限流规则
– 参数限流:key-resolver: "#{@parameterKeyResolver}"

@Bean
public KeyResolver parameterKeyResolver()
{
  return exchange ->
Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
  • IP限流:key-resolver: "#{@ipKeyResolver}"
@Bean
public KeyResolver ipKeyResolver()
{
  return exchange -> 
Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
   
分类:Java/OOP 作者:无限繁荣, 吴蓉 发表于:2024-06-03 15:55:02 阅读量:134
<<   >>


powered by kaifamiao