云原生之 Gateway 的 Filter 过滤器

简介: 云原生之 Gateway 的 Filter 过滤器

为什么会出现

通常情况下,出于安全方面的考虑,服务端提供的服务往往都会有一定的校验逻辑,例如用户登陆状态校验、签名校验等。

在微服务架构中,系统由多个微服务组成,所有这些服务都需要这些校验逻辑,此时我们就可以将这些校验逻辑写到 Spring Cloud Gateway 的 Filter 过滤器中。

Filter 的分类

Spring Cloud Gateway 提供了以下两种类型的过滤器,可以对请求和响应进行精细化控制


image.png

按照作用范围划分,Spring Cloud gateway 的 Filter 可以分为 2 类:

  • GatewayFilter:应用在单个路由或者一组路由上的过滤器。
  • GlobalFilter:应用在所有的路由上的过滤器。

GatewayFilter 网关过滤器


GatewayFilter 是 Spring Cloud Gateway 网关中提供的一种应用在单个或一组路由上的过滤器。它可以对单个路由或者一组路由上传入的请求和传出响应进行拦截,并实现一些与业务无关的功能,比如登陆状态校验、签名校验、权限校验、日志输出、流量监控等。


GatewayFilter 在配置文件(例如 application.yml)中的写法与 Predicate 类似,格式如下。

spring:
  cloud:
    gateway: 
      routes:
        - id: xxxx
          uri: xxxx
          predicates:
            - Path=xxxx
          filters:
            - AddRequestParameter=X-Request-Id,1024 #过滤器工厂会在匹配的请求头加上一对请求头,名称为 X-Request-Id 值为 1024
            - PrefixPath=/dept #在请求路径前面加上 /dept
            ……

Spring Cloud Gateway 内置了多达 31 种 GatewayFilter,下表中列举了几种常用的网关过滤器及其使用示例。


image.png

image.png

网关过滤器示例

下面我们通过一个实例来演示 GatewayFilter 的配置,步骤如下。

1. 在 micro-service-cloud-gateway-9527 的 application.yml 中在添加一个动态路由,配置内容如下

- id: provider_dept_get_routh
  uri: lb://MICROSERVICECLOUDPROVIDERDEPT #使用服务名代替上面的具体带端口
  predicates:
    - Path=/get/**
  filters:
    - PrefixPath=/dept #在请求路径上增加一个前缀 /dept

2. 重启 micro-service-cloud-gateway-9527,使用浏览器访“http://eureka7001.com:9527/get/1”,结果成功转发

GlobalFilter 全局过滤器


GlobalFilter 是一种作用于所有的路由上的全局过滤器,通过它,我们可以实现一些统一化的业务功能,例如权限认证、IP 访问限制等。当某个请求被路由匹配时,那么所有的 GlobalFilter 会和该路由自身配置的 GatewayFilter 组合成一个过滤器链。


Spring Cloud Gateway 为我们提供了多种默认的 GlobalFilter,例如与转发、路由、负载均衡等相关的全局过滤器。但在实际的项目开发中,通常我们都会自定义一些自己的 GlobalFilter 全局过滤器以满足我们自身的业务需求,而很少直接使用 Spring Cloud  Config 提供这些默认的 GlobalFilter。


全局过滤器实例

1. 在 net.biancheng.c.filter 包下,新建一个名为 MyGlobalFilter 全局过滤器配置类,代码如下。


package net.biancheng.c.filter;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
/**
* 自定义全局网关过滤器(GlobalFilter)
*/
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("进入自定义的全局过滤器 MyGlobalFilter" + new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
            log.info("参数 uname 不能为 null!");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        //过滤器的顺序,0 表示第一个
        return 0;
    }
}

2. 重启 micro-service-cloud-gateway-9527,使用浏览器访问“http://eureka7001.com:9527/dept/list”,我们会发现访问报 406 错误,控制台输出如下。

2022-11-1 16:25:39.450  INFO 19116 --- [ctor-http-nio-4] net.biancheng.c.filter.MyGlobalFilter    : CST 2021进入自定义的全局过滤器 MyGlobalFilter
2022-11-1 16:25:39.451  INFO 19116 --- [ctor-http-nio-4] net.biancheng.c.filter.MyGlobalFilter    : 参数 uname 不能为 null!

3. 使用浏览器访问“http://eureka7001.com:9527/dept/list?uname=123”,则会成功转发

Spring Cloud Gateway 工作流程


客户端将请求发送到 Spring Cloud Gateway 上。

Spring Cloud Gateway 通过 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送给 Gateway Web Handler。

Gateway Web Handler 通过指定的过滤器链(Filter Chain),将请求转发到实际的服务节点中,执行业务逻辑返回响应结果。

过滤器之间用虚线分开是因为过滤器可能会在转发请求之前(pre)或之后(post)执行业务逻辑。

过滤器(Filter)可以在请求被转发到服务端前,对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等。

过滤器可以在响应返回客户端之前,对响应进行拦截和再处理,例如修改响应内容或响应头、日志输出、流量监控等。

响应原路返回给客户端。


总而言之,客户端发送到 Spring Cloud Gateway 的请求需要通过一定的匹配条件,才能定位到真正的服务节点。在将请求转发到服务进行处理的过程前后(pre 和 post),我们还可以对请求和响应进行一些精细化控制。


Predicate 就是路由的匹配条件,而 Filter 就是对请求和响应进行精细化控制的工具。有了这两个元素,再加上目标 URI,就可以实现一个具体的路由了。


83b341897f5b4064981697e7f5ec4735.png


相关文章
|
6月前
|
缓存 Java API
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
|
11月前
|
负载均衡 Cloud Native Java
【云原生】Spring Cloud Alibaba 之 Gateway 服务网关实战开发
【云原生】Spring Cloud Alibaba 之 Gateway 服务网关实战开发
1871 0
|
4月前
|
Prometheus Kubernetes Cloud Native
云原生周刊:Argo Rollouts 支持 Kubernetes Gateway API 1.0 | 2024.7.1
探索开源世界:Kubetools的推荐系统[Krs](https://github.com/kubetoolsca/krs)助力K8s优化,追踪K8s组件清单,指引IAC集成。阅读建议: Prometheus与Thanos的进化故事,Adidas容器平台管理经验,K8s请求实现详解。关注云原生:Argo Rollouts支持Gateway API 1.0,Kubewarden v1.14强化策略与镜像安全。
|
2月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
32 3
|
5月前
|
Java API 开发者
Spring Cloud Gateway中的GlobalFilter:构建强大的API网关过滤器
Spring Cloud Gateway中的GlobalFilter:构建强大的API网关过滤器
325 0
|
6月前
|
监控 Cloud Native 安全
【阿里云云原生专栏】云原生下的API管理:阿里云API Gateway的应用场景与优势
【5月更文挑战第23天】阿里云API Gateway是高性能的API托管服务,适用于微服务API聚合、安全管理及流量控制。它提供统一入口、多种认证方式和流量控制策略,确保服务稳定性。具备高度可扩展性、丰富插件生态和简化API生命周期管理等特点。通过简单步骤,如创建API、配置后端服务、设置认证和发布,即可快速上手。作为云原生时代的API管理解决方案,阿里云API Gateway助力企业高效、安全地管理API,推动业务创新和数字化转型。
95 1
|
6月前
|
Java 微服务 Spring
SpringCloud&Gateway全局过滤器
SpringCloud&Gateway全局过滤器
76 1
|
6月前
|
JSON 安全 关系型数据库
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证
|
Java Spring
Spring Cloud Gateway 源码剖析之Filter Chain过滤器链
Spring Cloud Gateway 源码剖析之Filter Chain过滤器链
272 0
|
存储 人工智能 运维
云原生AIGC工作台(AIGC-Gateway)助力企业加速AIGC落地
为了解决企业内部落地AIGC引擎的通用性问题,阿里云与行者AI通过CloudNativeGame社区一起开源了AIGC-Gateway项目,降低企业内部AIGC落地的难度与费用,真正做到开箱即用,即开即用。
1375 1