Spring Cloud Gateway 过滤器种类

Spring Cloud Gateway 根据作用范围划分为 GatewayFilterGlobalFilter

SpringCloud-gataway官网介绍

filter 的作用和生命周期

由 filter 工作流程点,可以知道 filter 有着非常重要的作用,在 “pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在 “post” 类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等

作用

网关过滤器用于拦截并链式处理 Web 请求,可以实现横切与应用无关的需求,比如:鉴权、限流、日志输出等

生命周期

Spring Cloud Gateway 同 zuul 类似,有 “pre” 和“post”两种方式的 filter。客户端的请求先经过 “pre” 类型的 filter,然后将请求转发到具体的业务服务,比如上图中的 user-service,收到业务服务的响应之后,再经过 “post” 类型的 filter 处理,最后返回响应到客户端。filter 从作用范围可分为另外两种,一种是针对于单个路由的 gateway filter,它在配置文件中的写法同 predict 类似;另外一种是针对于所有路由的 global gateway filer

网关过滤器 GatewayFilter

过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。过滤器可以限定作用在某些特定请求路径上。可以实现横切与应用无关的需求,比如:安全、访问超时的设置等。修改传入的 HTTP 请求或传出 HTTP 响应。Spring Cloud Gateway 包含许多内置的网关过滤器工厂,一共 22 个。包括头部过滤器、路径过滤器、Hystrix 过滤器和重写请求 URL 的过滤器,还有参数和状态码等其他类型的过滤器。根据过滤器工程的用途来划分,可以分为以下几种:Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter 和 Hystrix。 Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。

GatewayFilter 工厂同上一篇介绍的 Predicate 工厂类似,都是在配置文件 application.yml 中配置,遵循了约定大于配置的思想,只需要在配置文件配置 GatewayFilter Factory 的名称,而不需要写全部的类名,比如 AddRequestHeaderGatewayFilterFactory 只需要在配置文件中写 AddRequestHeader,而不是全部类名。在配置文件中配置的 GatewayFilter Factory 最终都会相应的过滤器工厂类处理。

1、AddRequestHeader

1、描述

1、用于向下游服务 添加 请求头,
2、支持 uri variables

2、参数

1、name:向下游服务传递请求头的 key
2、value:向下游服务传递请求头的 value

3、示例

1、方式一、添加一个固定的请求头

spring:
  cloud:
    nacos:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - AddRequestHeader=x-token,xxxxx

表示会向下游服务传递一个 x-token 的请求头,值是 xxxxx

2、配合 uri variables 添加动态请求头

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-02
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne/{productId}
          filters:
            - AddRequestHeader=x-token,xxxxx-{productId}

表示会向下游服务传递一个 x-token 的请求头,值是 xxxxx-匹配上的productId的值

2、AddRequestParameter

1、描述

用于向下游服务 添加一个请求参数

2、参数

1、name:添加的参数 key
2、value:添加的参数 value,可以支持 Path 或 Host 中的 uri variables

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - AddRequestParameter=username,zhangsan

向下游服务增加一个 username = zhangsan 的请求参数

3、AddResponseHeader

1、描述

向下游的响应中增加一个 响应头。

2、参数

1、name:添加的响应头的 key
2、value:添加的响应头的 value,可以支持 Path 或 Host 中的 uri variables

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - AddResponseHeader=encryption,false

向下游服务响应增加一个 encryption = false 的响应头

4、DedupeResponseHeader

1、描述

移除重复的请求头

2、参数

1、name:需要移除的重复的响应头,多个以 空格 分隔
2、strategy:重复时,移除的策略,默认是RETAIN_FIRST, 即保留第一个头

  1. RETAIN_FIRST:保留第一个值
  2. RETAIN_LAST:保留最后一个值
  3. RETAIN_UNIQUE:保留所有的不重复的值

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - DedupeResponseHeader=x-token Access-Control-Allow-Credentials Access-Control-Allow-Origin,RETAIN_FIRST

移除上方指定的重复的响应头,并且保留第一个出现的。

5、MapRequestHeader

1、描述

fromHeader 参数的值 追加到 toHeader 参数中。

  1. fromHeader 在 header 中不存在,那么没有什么影响。

  2. fromHeader 存在

  3.  toHeader 存在,那么往配置中 toHeader 对应的 header 中追加 fromHeader对应的值 
    
    
    
  4. toHeader 不存在,那么往 header 中增加一个header ,key: 配置中的toHeader的值,value: fromHeader 在header中的值
    
    
    

2、参数

1、fromHeader:从请求参数中获取header的值
2、toHeader:向header中设置一个 header, key 是 toheader 的值,value 是 fromHeader 的值

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - MapRequestHeader=from-header,x-token

即会向 request 中增加一个 key 为 x-token 的 header , 值为 header 中 from-header 对应的值。(存在多种情况,参考描述

6、Prefix

1、描述

为匹配到的路由,在转发到下游服务时,增加一个前缀prefix

2、参数

1、prefix:需要增加的路径前缀

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/findOne
          filters:
            - PrefixPath=/product

访问 http:// 网关 ip:port/findOne ⇒ 转发到下游服务地址 http://product-provider/product/findOne 增加了一个前缀。

7、PreserveHostHeader

1、描述

它表示在 Spring Cloud Gateway 转发请求的时候,保持客户端的Host信息不变,然后将它传递到下游服务器中。

2、参数

没有参数

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - PreserveHostHeader

8、RemoveRequestHeader

1、描述

移除请求头中的参数

2、参数

1、name:需要移除的请求头

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - RemoveRequestHeader=x-token

9、RemoveResponseHeader

1、描述

移除响应头

2、参数

1、name:需要移除的响应头

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - RemoveResponseHeader=x-token

9、RemoveRequestParameter

1、描述

移除请求参数,往下游服务传递时,此参数就没有来

2、参数

1、name:需要移除的请求参数

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - RemoveRequestParameter=password

10、RewritePath

1、描述

根据正则表达式,执行路径重写

2、参数

1、regexp:匹配的正则表达式
2、replacement:需要替换成的字符串
注意:
1、在yml配置中 $ 需要写成 $\
2、路径替换规则是: path.replaceAll(regexp,replacement)

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/admin/product/findOne
          filters:
            - RewritePath=/admin(?<segment>/?.*), $\{segment} # 当访问/admin/product/findOne 将会替换成 /product/findOne

页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 /product/findOne

11、StripPrefix

1、描述

移除路径前缀,比如访问: /admin/aa/bb/cc 实际的下游服务器地址是 /bb/cc 则可以使用这个实现

2、参数

1、parts:请求的路径按照/分隔后,需要跳过的部分,从 1 开始。

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/admin/product/findOne
          filters:
            - StripPrefix=1 # 当访问/admin/product/findOne 将会替换成 /product/findOne

页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 /product/findOne

12、RequestSize

1、描述

配置请求体的大小,当请求体过大时,将会返回 413 Payload Too Large

2、参数

1、maxSize:请求体的大小

3、示例

spring:
  cloud:
    gateway:
      routes:
        - id: product-provider-01
          uri: lb://product-provider
          predicates:
            - Path=/product/findOne
          filters:
            - name: RequestSize
              args:
                maxSize: 1B

此处需要通过 filters[index].args.maxSize 配置,否则不生效。

13、ModifyRequestBody

1、描述

修改传递到下游服务 RequestBody 的值,比如我们所有的经过网关的服务,到达下游服务时,都需要将 用户当前的用户名和数据权限传递下去,此时就可以使用这个。

2、需求:

修改原始服务的参数,增加usernameroles参数传递到下游服务。

3、路由配置,只可通过 Java 代码来配置

@Configuration
public class RouteConfig {
 
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("product-provider", predicateSpec -> predicateSpec.path("/product/modifyRequestBody")
                        .filters(gatewayFilterSpec -> gatewayFilterSpec.modifyRequestBody(String.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> {
                            Map<String, Object> params = new HashMap<>(16);
                            params.put("old", s);
                            params.put("username", "v_huan");
                            params.put("roles", "ROLE_ADMIN");
                            return Mono.just(params);
                        })).uri("lb://product-provider")).build();
    }
}

全局过滤器

全局过滤器不需要在配置文件中配置,作用在所有的路由上,最终通过 GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器,它是请求业务以及路由的 URI 转换为真实业务服务请求地址的核心过滤器,不需要配置系统初始化时加载,并作用在每个路由上。

当某个请求被路由匹配时,那么所有的全局过滤器 (GlobalFilter) 和路由匹配到的 GatewayFilter 会组合成一个过滤器链,排序规则是通过 Spring 的 Ordered 来排序。
GlobalFilter 有 pre 和 post2 个执行阶段,优先级越高 pre 阶段执行越早, post 阶段执行越迟。
编写一个全局过滤器需要实现 GlobalFilter 接口

下面这些是 Gateway 内置的全局过滤器,已经在所有路由生效

Spring Cloud Gateway 根据作用范围划分为 GatewayFilter 和 GlobalFilter,二者区别如下:

  • GatewayFilter : 需要通过 spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过 spring.cloud.default-filters 配置在全局,作用在所有路由上
  • GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过 GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器,它为请求业务以及路由的 URI 转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。

参考资料:https://www.jianshu.com/p/394e11981692 Spring Cloud Gateway

猜你喜欢

转载自blog.csdn.net/caidingnu/article/details/129420242