在频繁的网络请求时,服务有时候也会受到很大的压力,尤其是那种网络攻击,非法的。这样的情形有时候需要作一些限制。例如:限制对方的请求,这种限制可以有几个依据:请求IP、用户唯一标识、请求的接口地址等等。
当前限流的方式也很多:Spring cloud 中在网关本身自带限流的一些功能,基于 redis 来做的。同时,阿里也开源了一款:限流神器 Sentinel。今天我们主要围绕这两块来实战微服务的限流机制。
首先讲 Spring cloud 原生的限流功能,因为限流可以是对每个服务进行限流,也可以对于网关统一作限流处理。
一、实战基于 Spring cloud Gateway 的限流
pom.xml引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
其基础是基于redis,所以:
spring:
application:
name: gateway-service
redis: #redis相关配置
database: 8
host: localhost
port: 6379
password: 123456 #有密码时设置
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
timeout: 10000ms
接下来需要注入限流策略的 bean:
@Primary
@Bean(value = "ipKeyResolver")
KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
//return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
//return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
/**
* API限流
* @return
*
*/
@Bean(value = "apiKeyResolver")
KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
/**
* 请求路径中必须携带userId参数
* 用户限流
* @return
*
*/
@Bean(value = "userKeyResolver")
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
这里引入ipKeyResolver、apiKeyResolver、userKeyResolver三种策略,可以利用注解 @Primary 来决定其中一个被使用。
注入bean后,需要在配置中备用:
spring:
application:
name: gateway-service
redis: #redis相关配置
database: 8
host: localhost
port: 6379
password: 123456 #有密码时设置
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
timeout: 10000ms
cloud:
kubernetes:
discovery:
all-namespaces: true
gateway:
discovery:
locator:
enabled: true
lowerCaseServiceId: true
routes: #路由配置:参数为一个List
- id: cas-server #唯一标识
uri: lb://cas-server-service #转发的地址,写服务名称
order: -1
predicates:
- Path=/cas-server/** #判断匹配条件,即地址带有/ribbon/**的请求,会转发至lb:cas-server-service
filters:
- StripPrefix=1 #去掉Path前缀,参数为1代表去掉/ribbon
- name: RequestRateLimiter #基于redis