有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
网关可以做很多的事情,比如,限流,当我们的系统 被频繁的请求的时候,就有可能 将系统压垮,所以 为了解决这个问题,需要在每一个微服务中做限流操作,但是如果有了网关,那么就可以在网关系统做限流,因为所有的请求都需要先通过网关系统才能路由到微服务中。
2.5.1 令牌桶算法讲解
令牌桶算法是常见的限流算法之一,我们讲解一下漏桶算法:
1 2 3 4 5 6 7 8 9
| 1)所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;
2)根据限流大小,设置按照一定的速率往桶里添加令牌;
3)桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;
4)请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;
5)令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流
|
令牌桶算法的实现,有很多技术,Guaua 是其中之一,redis 客户端也有其实现。
2.5.2 限流案例
spring cloud gateway 默认使用 redis 的 RateLimter 限流算法来实现,外面来简要实现一下:
1、引入依赖
首先需要引入 redis 的依赖:
1 2 3 4 5 6 7 8 9 10 11 12
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
|
同时不要忘记 Redis 配置:
1 2 3 4 5
| redis:
host: 127.0.0.1
port: 6379
|
2、定义 KeyResolver
在 Application 引导类中添加如下代码,KeyResolver 用于计算某一个类型的限流的 KEY 也就是说,可以通过 KeyResolver 来指定限流的 Key。
我们可以根据 IP 来限流,比如每个 IP 每秒钟只能请求一次,在 GatewayApplication 定义 key 的获取,获取客户端 IP,将 IP 作为 key,如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
@Bean(name="ipKeyResolver")
public KeyResolver userKeyResolver() {
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String hostName = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
System.out.println("hostName:"+hostName);
return Mono.just(hostName);
}
};
}
|
在路由中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| gateway:
routes:
- id: hailtaxi-driver
uri: lb://hailtaxi-driver
predicates:
- Path=/driver/**
- Cookie=username,itheima
- Header=token,^(?!\d+$)[\da-zA-Z]+$
- Method=GET,POST
- Token=Authorization
filters:
- PayMethod=alipay, 业务整合
- name: RequestRateLimiter
args:
key-resolver: "#{@ipKeyResolver}"
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 1
|
参数说明:
1 2 3 4 5
| redis-rate-limiter.replenishRate是您希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶填充的速率
redis-rate-limiter.burstCapacity 是指令牌桶的容量,允许在一秒钟内完成的最大请求数, 将此值设置为零将阻止所有请求。
key-resolver: “#{@ipKeyResolver}” 用于通过 SPEL 表达式来指定使用哪一个 KeyResolver.
|
如上配置:表示 一秒内,允许 一个请求通过,令牌桶的填充速率也是一秒钟添加一个令牌。最大突发状况 也只允许 一秒内有一次请求,可以根据业务来调整。
我们请求 http://localhost:8001/driver/info/1?token=aa
执行测试,效果如下: