网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性。
使用的是Spring Cloud Gateway作为网关,分享一下其中的限流操作,目前限流使用的是基于Redis的实现,我们需要增加对应的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
定义Spring Cloud Gateway中的key-resolver:“#{@ipAddressKeyResolver}” #SPEL表达式去对应bean,key就是bean要取得名字,如remoteAddrKeyResolver:
IP限流:
/**
* 根据 HostName 进行限流
* @return
*/
@Primary
@Bean(value = "remoteAddrKeyResolver")
public KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
API限流:
/**
* 根据api接口来限流
* @return
*/
@Bean(name="apiKeyResolver")
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
User限流:
/**
* 用户限流
* 使用这种方式限流,请求路径中必须携带userId参数。
* 提供第三种方式
* @return
*/
@Bean("userKeyResolver")
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
可以根据集体情况自己添加新的限流策略
关于配置,可以在需要限流的服务中增加过滤器信息
server: port: 20001 spring: redis: host: 127.0.0.1 port: 6379 cloud: gateway: routes: - id: micro-activity uri: lb://micro-activity predicates: - Path=/api/activity/** filters: - name: RequestRateLimiter //名称必须是这个 args: redis-rate-limiter.replenishRate: 100 //允许用户每秒处理多少个请求 redis-rate-limiter.burstCapacity: 100 //令牌桶的容量,允许在一秒钟内完成的最大请求数(用的是令牌桶算法) key-resolver: "#{@ipKeyResolver}" //使用SpEL按名称引用bean