入不敷出 1)、所有的请求在处理之前都需要拿到一个可用的令牌才会被处理; 2)、根据限流大小,设置按照一定的速率往桶里添加令牌; 3)、桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝; 4)、请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除; 5)、令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流; 3 Gateway 结合 redis 实现请求量限流 Spring Cloud Gateway 已经内置了一个 RequestRateLimiterGatewayFilterFactory,我们可以直接使用。 目前 RequestRateLimiterGatewayFilterFactory 的实现依赖于 Redis,所以我们还要引入spring-boot-starter-data-redis-reactive。 3.1 添加依赖
org.springframework.boot
spring-boot-starter-data-redis-reactive
3.2 修改配置文件
3.3 配置文件说明 在上面的配置文件,配置了 redis 的信息,并配置了 RequestRateLimiter 的限流过滤器,该过滤器需要配置三个参数: burstCapacity:令牌桶总容量。 replenishRate:令牌桶每秒填充平均速率。 key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据
3.4 创建配置类 RequestRateLimiterConfig
@Configuration
public class RequestRateLimiterConfig {
/**
* IP 限流
* 把用户的 IP 作为限流的 Key
*
* @return
*/
@Bean
@Primary
public KeyResolver hostAddrKeyResolver() {
return (exchange) -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
/**
* 用户 id 限流
* 把用户 ID 作为限流的 key
*
* @return
*/
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
/**
* 请求接口限流
* 把请求的路径作为限流 key
*
* @return
*/
@Bean
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
} 3.5 启动快速访问测试 http://localhost/info?token=asdad 快速访问后报 429
查看 redis