比如说我们有一个网站,每天的请求量不是很多,忽然有一天的某一个时刻,涌进来一大堆人进行访问你的网站,没几分钟整个服务挂了,并引发连锁反应导致整个系统崩溃。
像这种情况出现后如何去应对?这就是这篇博客要说的:限流。
我们通过某种算法,让用户请求达到一定的时候,再进来的请求进行拒绝请求、排队、等待、降级等处理。
二、Gateway 令牌桶限流先来了解一下 Gateway 的令牌桶限流,来看下图:
首先我们去设定一个令牌桶,这个桶的话是有恒定大小,比如说容量是 5。我们按照一定速率(好比一秒生成一个令牌)往桶里面存放令牌,如果某一个时刻桶放满了,那么我们就将生成的令牌丢弃掉。
接下来请求来了,客户端发出一个请求后,先去令牌桶中获取令牌,如果获取到,就继续往下执行,如果没有获取到,我们让请求中断,并提示给用户。
这样一来,我们可以保证最大的并发量,也就是我们令牌桶的容量。通过恒定的速率生成令牌,能够让请求处理的更均匀,不会出现某一时刻大量请求涌进。
三、Gateway 令牌桶的实现Gateway 给我们提供了一个 RequestRateLimiter GatewayFilter 的工厂,我们就用它来进行实现。
1. 首先我们去定义一个 KeyResolverConfiguration 的配置类,该配置类主要来配置限流规则
@Configuration
public class KeyResolverConfiguration {
private Logger logger = LoggerFactory.getLogger(KeyResolverConfiguration.class);
@Bean
public KeyResolver uriKeyResolver() {
// return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
return new KeyResolver() {
@Override
public Mono resolve(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
logger.info(request.getURI().getPath());
return Mono.just(request.getURI().getPath());
}
};
}
}
在这个配置类中,通过实例化一个 KeyResolver,而 KeyResolver 就是限流的具体规则。当前代码我们是根据请求的路径进行限流。
2. 配置好之后,我们还需要去引入 Redis
org.springframework.boot spring-boot-starter-data-redisorg.apache.commons commons-pool2
yml 也配置一下
# 数据源配置
spring:
redis:
host: localhost
# password: 123456
port: 6379
timeout: 3000ms
database: 2
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: 2000ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0
3. 接下来顺便再 yml 再对令牌桶进行配置。
# 数据源配置
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://localhost:3000/
predicates:
- Path=/normal/**
filters:
- Something
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量
redis-rate-limiter.requestedTokens: 1 # 一个请求需要消费的令牌数
key-resolver: "#{@uriKeyResolver}"
我们这里需要配置:令牌桶每一秒填充速度,这里是一秒一个;令牌桶的总容量,这里我们一个桶只能存放两个令牌;一个请求需要消费的领排数,这里我们是一个令牌消费一个。
还有一个是 key-resolver,就是我们的限流规则,这里根据 Gateway 官网提供的文档,我们可以写成这样,里面的值就是我们刚刚定义的 bean。
四、Gateway 令牌桶测试我们启动 Redis、Gateway、业务模块进行测试。
可以看到,慢慢的请求是可以正常提供服务,现在我们刷新的快一点~~~
这里报 HTTP 429 异常了,429 的意思是:Too Many Requests,也就是太多的请求了。除去这里,Redis 也是有变化的。
在限流之后,这里也是会有记录的。
Gateway 网关的限流规则可以自己进行定义,如果不知道有那些,自己百度进行查看学习。
这一讲就讲到这里,有问题可以联系我:QQ 2100363119,欢迎大家访问我的个人网站:https://www.lemon1234.com



