前言
Spring Cloud Gateway 过滤器的种类有30多种。
官文文档地址:Spring Cloud Gatewayhttps://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
Spring Cloud Gateway大体可以分为下面两种类型的过滤器:
1、内置的过滤器
1.1、内置的局部过滤器
1.2、内置的全局过滤器
2、自定义过滤器
举例一些常见的使用
1、内置的过滤器
1.1、内置的局部过滤器
① AddRequestHeader
给后续请求的接口添加Header信息。
AddRequestHeader有两个参数一个是name--向下游的服务传递请求头的key,一个是value--向下游服务传递请求头的value
配置如下所示:
key:X-Request-test
value:wx
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- AddRequestHeader=X-Request-test, wx
server:
port: 10086
通过调用user-service模块的服务,打印请求头信息
打印的结果如下:
② AddRequestParameter
用于向下游服务 添加一个请求参数。等号后面第一个是参数名称,最后一个是参数值
配置如下所示:
参数名称:name
参数值:wx
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- AddRequestParameter=name, wx
打印参数信息
@PrefixPath
在请求的url前面添加前缀,例如请求的是/user,添加PrefixPath为 /new,那么访问的地址就变为了“/new/user”,配置如下:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- PrefixPath=/new
④ RequestRateLimiter
用于限制请求的频率。它可以对指定的路由或服务进行频率限制,以确保对应的服务不会过于频繁地被请求。
Spring Cloud Gateway中的RequestRateLimiter通过集成各种限流算法,如令牌桶算法(Token Bucket Algorithm)、漏桶算法(Leaky Bucket Algorithm)等,实现了对请求的限制。你可以根据自己的需求选择适合的算法和参数,以控制每个实例或用户在一定时间范围内可以发送的请求数量。
使用RequestRateLimiter可以有效地防止DDoS攻击、限制恶意用户的请求频率,以及平衡和保护后端服务的资源使用。它是Spring Cloud Gateway中提供的一种重要的流量控制和保护功能。
Spring Cloud Gateway 当前版本支持和Redis一起实现限流功能,实现步骤有三步:
1. 添加Redis框架依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
2.创建限流规则
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public class IpAddressKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress()
.getHostString());
}
}
3.配置限流过滤器
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 1
keyResolver: '#{@ipAddressKeyResolver}'
data:
redis:
host: 127.0.0.1
port: 16379
database: 0
name必须为“RequestRateLimiter”内置限流过滤器,其它参数的含义如下:
- redis-rate-limiter.replenishRate:令牌填充速度(每秒允许请求数)。
- redis-rate-limiter.burstCapacity:令牌桶容量(最大令牌数量)。
- keyResolver:根据哪个 key 进行限流,它的值是 spEL 表达式。
spEL(Spring Expression Language)是Spring框架中的一种表达式语言,用于在配置文件中执行运算、访问对象属性等。在SpEL中,可以使用运算符、函数以及访问对象属性等,实现复杂的表达式求值。下面是一些spEL表达式的例子:
计算表达式:
- #{2 + 3}:计算2加上3的结果。
- #{5 > 3}:判断5是否大于3,结果为true。
访问属性:
- #{person.name}:获取person对象的name属性的值。
- #{person.age > 18}:判断person对象的age是否大于18。
调用函数:
- #{T(java.lang.Math).random()}:调用Math类的random函数,生成一个随机数。
条件判断:
- #{score >= 60 ? '及格' : '不及格'}:当score大于等于60时返回'及格',否则返回'不及格'。
集合操作:
- #{list.size()}:获取list集合的长度。
- #{list[0]}:获取list集合中的第一个元素。
正则表达式:
- #{'abc123' matches 'd+'}:判断字符串是否匹配数字正则表达式。
注意事项:
Spring Cloud Gateway 配合 Redis 实现限流的时候,对 Redis 的版本是有要求的。Redis Server的版本要在 5.X以上,因为它调用了一个高版本的函数。
⑤ Retry
请求重试过滤器配置
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms #第一次重试间隔
maxBackoff: 50ms #最大重试间隔
factor: 2 # firstBackoff * (factor ^ n) 重试系数
basedOnPreviousValue: false # 基于上次重试时间加上重试系数来计算
注意事项:重试过滤器的 name 一定要等于“Retry”,因为“Retry”是内置重试过滤器的名字,改为其它框架的就识别不到了。
参数解析:
- retries:重试次数。
- statuses:重试的 HTTP 状态代码取值请参考:org.springframework.http.HttpStatus,状态码匹配上才会重试。
- methods:重试的 HTTP 方法,方法类型匹配上才会重试。取值 GET,HEAD,POST,PUT,PATCH,DELETEOPTIONS,TRACE。
- series:状态码配置(分段),符合的某段状态码才会进行重试逻辑,默认值是SERVER_ERROR,值是 5,也就是 5XX(5 开头的状态码),共有 5 个值:
1XX:INFORMATIONAL
2XX:SUCCESSFUL
3XX:REDIRECTION
4XX:CLIENT ERROR
5XX:SERVER ERROR - backoff:重试指数配置策略,默认关闭。
1.2、内置全局过滤器
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway: # 配置网关
routes:
- id: userservice-headers
uri: lb://user-service-gateway
predicates:
- Path=/user/**
filters:
- AddResponseHeader=gateway-flag,wx
defaultFilters:
- AddResponseHeader=default-filters,wx121
server:
port: 10086
这里注意,当局部过滤器跟全局过滤器使用的参数名字一样时,不会冲突,两个可以一起使用
2、自定义全局过滤器
可以使用Spring Cloud Gateway 提供的全局过滤器来实现统一认证授权,下面的是模板参考:
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 得到 request、response 对象
ServerHttpRequest request=exchange.getRequest();
ServerHttpResponse response=exchange.getResponse();
// 业务逻辑代码
if(request.getQueryParams().getFirst("auth")==null){
// 权限有问题返回,并结束执行
response.setStatusCode(HttpStatus.FORBIDDEN);
return response.setComplete();
}
// 此步骤正常,执行下一步
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 此值越小越早执行
return 1;
}
}
以登录授权作为模拟,这里要求要有username跟password两个参数都要为admin.
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, // 执行事件
GatewayFilterChain chain) { //过滤器链
//需求:未登录判断逻辑:当参数中 username=admin && password=admin
// 继续执行,否则推出执行
// 对象都存储在exchange里面,得到 request、response 对象
ServerHttpRequest request=exchange.getRequest();
ServerHttpResponse response=exchange.getResponse();
// 业务逻辑代码
// request.getQueryParams() 获取参数
String username = request.getQueryParams().getFirst("username");
String password = request.getQueryParams().getFirst("password");
if(username !=null && username.equals("admin") &&
password != null && password.equals("admin")){
// 已经登录,执行下一步
return chain.filter(exchange);
}else{
// 设置无权限 401
response.setStatusCode(HttpStatus.UNAUTHORIZED);
// 执行完成,不用继续执行后续流程了
return response.setComplete();
}
}
@Override
public int getOrder() {
// 此值越小越早执行
return 1;
}
}
所以在访问的时候,要跟以下地址一样文章来源:https://www.toymoban.com/news/detail-844079.html
http://localhost:10086/user/getname?username=admin&password=admin文章来源地址https://www.toymoban.com/news/detail-844079.html
到了这里,关于Spring Cloud Gateway 过滤器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!