Spring Cloud Gateway是Spring Cloud提供的一种轻量级网关解决方案,它基于异步非阻塞的Reactor模型,可以通过配置路由规则实现请求转发和路由策略。除此之外,Spring Cloud Gateway还支持过滤器的配置,通过过滤器可以在请求到达网关之前或者离开网关之后对请求进行处理和控制。
过滤器分类
Spring Cloud Gateway的过滤器分为两种类型:全局过滤器和局部过滤器。
- 全局过滤器
全局过滤器会对所有的路由进行拦截和处理,通过实现GlobalFilter接口来实现。它可以对请求进行统一的处理和控制,比如添加请求头、记录日志等。
- 局部过滤器
局部过滤器只对某个具体的路由进行拦截和处理,通过在配置文件中配置spring.cloud.gateway.routes.filters属性来实现。局部过滤器可以通过实现GatewayFilterFactory接口或者继承AbstractGatewayFilterFactory抽象类来实现。
过滤器功能
Spring Cloud Gateway的过滤器可以实现如下功能:
- 鉴权
通过过滤器可以实现用户鉴权的功能,对未授权的请求进行拦截和处理。
- 日志记录
可以通过过滤器记录请求的日志信息,方便进行故障排查和系统分析。
- 响应转换
可以通过过滤器对返回结果进行转换和处理,比如转换成JSON格式、添加响应头等。
- 限流
可以通过过滤器实现流量控制和限流的功能,对流量进行管理和调度。
- 请求重试
可以通过过滤器实现请求重试的功能,对于请求失败或者超时的情况,可以自动进行重试。
- 请求转发
可以通过过滤器实现请求的转发和重定向,对于不同的请求可以采用不同的策略进行处理。
全局过滤器和局部过滤器示例
以下是一个示例,通过自定义全局过滤器来实现请求日志记录的功能:
代码语言:javascript复制@Component
public class LoggingFilter implements GlobalFilter, Ordered {
private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("Request URI: {}", exchange.getRequest().getURI().toString());
return chain.filter(exchange).doAfterSuccessOrError((aVoid, throwable) -> {
if (throwable != null) {
logger.error("Request processing failed", throwable);
} else {
logger.info("Request processing succeeded");
}
});
}
@Override
public int getOrder() {
return -1;
}
}
在上面的示例中,LoggingFilter是一个全局过滤器,它实现了GlobalFilter和Ordered接口,并重写了filter和getOrder方法。在filter方法中,记录了请求的URI信息,并通过chain.filter(exchange)方法将请求交给下一个过滤器处理,最后通过doAfterSuccessOrError方法记录请求处理的结果。在getOrder方法中,指定了过滤器的执行顺序,-1表示在所有的路由之前执行。
以下是一个示例,通过自定义局部过滤器来实现请求鉴权的功能:
代码语言:javascript复制@Component
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {
public AuthFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String token = exchange.getRequest().getHeaders().getFirst("token");
if (token == null || !token.equals(config.getToken())) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
};
}
public static class Config {
private String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
}
在上面的示例中,AuthFilter是一个局部过滤器,它继承了AbstractGatewayFilterFactory抽象类,并通过泛型参数指定了配置类Config。在apply方法中,首先从请求头中获取token参数,然后与配置文件中的token进行比较,如果不一致,则返回401状态码。否则将请求交给下一个过滤器处理。
在配置文件中,可以通过spring.cloud.gateway.routes.filters属性来指定要使用的过滤器,如下所示:
代码语言:javascript复制spring:
cloud:
gateway:
routes:
- id: auth-service
uri: http://localhost:8081
predicates:
- Path=/auth/**
filters:
- AuthFilter
- StripPrefix=1
在上面的示例中,指定了一个路由,它的ID是auth-service,目标地址是http://localhost:8081,匹配的路径是/auth/**,同时指定了两个过滤器,分别是AuthFilter和StripPrefix。其中,AuthFilter是自定义的局部过滤器,用于请求鉴权,StripPrefix是Spring Cloud Gateway提供的全局过滤器,用于移除请求路径的前缀。