gateway默認給我們提供了限流實現,也就是網關攔截器RequestRateLimiter。
6.1 令牌桶限流算法 RequestRateLimiter底層實現是令牌桶算法;
令牌桶內存儲令牌,令牌桶需要設置令牌容量,也就是系統最大的並發大; 以一定的速率生成令牌(具體速率根據系統性能設置),放到令牌桶,如果桶慢了,則丟棄; 客戶端來一個請求,則先去令牌桶獲取令牌,拿到令牌,則處理請求,否則 丟棄或者返回失敗;
令牌桶算法的優點: (1)通過恆定的速率生成令牌桶,能夠讓請求處理更均勻,不會出現短時間大量的請求處理; (2)比較友好的控制高並發;

6.2 Gateway網關限流實例
Spring Cloud Gateway官方提供了 RequestRateLimiterGatewayFilterFactory 過濾器工廠,使用Redis 和 Lua 腳本實現了令牌桶,來實現網關限流; 添加下Redis依賴:
<!-- spring boot redis 緩存引入 --> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 緩存連接池 --> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
6.2.1 URI限流
配置類:
package com.java1234.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;
/**
* 限流規則配置類
* @author java1234
*/
@Configuration
public class KeyResolverConfiguration {
@Bean
public KeyResolver pathKeyResolver(){
/*return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getURI().getPath());
} };*/
return exchange -> Mono.just(exchange.getRequest().getURI().getPath()); // URI限流
} }
yml配置:
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: rateLimiter
uri: http://localhost:8080/
predicates:
- Path=/product/**
filters:
- name: RequestRateLimiter # 限流過濾器
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率 r
redis-rate-limiter.burstCapacity: 2 # 令牌桶總容量
redis-rate-limiter.requestedTokens: 1 # 一個請求需要消費的令牌數
key-resolver: "#{@pathKeyResolver}"
redis: # redis配置
host: 192.168.0.103 # IP
port: 6379 # 端口
password: # 密碼
connect-timeout: 10s # 連接超時時間
lettuce: # lettuce redis客戶端配置
pool: # 連接池配置
max-active: 8 # 連接池最大連接數(使用負值表示沒有限制) 默認 8
max-wait: 200s # 連接池最大阻塞等待時間(使用負值表示沒有限制) 默認 -1
max-idle: 8 # 連接池中的最大空閑連接 默認 8
min-idle: 0 # 連接池中的最小空閑連接 默認 0
訪問過多之后,報429錯誤;
6.2.2 參數限流 配置類:
package com.java1234.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;
/**
* 限流規則配置類
* @author java1234
*/
@Configuration
public class KeyResolverConfiguration {
@Bean
public KeyResolver parameterKeyResolver(){
/*return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return
Mono.just(exchange.getRequest().getQueryParams().getFirst("token"));
}
};*/
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("token")); // 參數限流
} }
請求帶一個參數:http://localhost/product/32?token=fdafa
6.2.3 IP限流 配置類:
package com.java1234.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 限流規則配置類 * @author java1234 */ @Configuration public class KeyResolverConfiguration { @Bean public KeyResolver ipKeyResolver(){ /*return new KeyResolver() { @Override public Mono<String> resolve(ServerWebExchange exchange) { return Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); } };*/ return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); // IP限流 } }
