• 【云原生&微服务>SCG网关篇六】Spring Cloud Gateway内置的18种Filter使用姿势


    一、前言

    至此微服务网关系列文章已出:

    1. 【云原生&微服务>SCG网关篇一】为什么要有网关、生产环境如何选择网关
    2. 云原生&微服务>SCG网关篇二】生产上那些灰度发布方式
    3. 【云原生&微服务>SCG网关篇三】Spring Cloud Gateway是什么、详细使用案例
    4. 云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用
    5. 【云原生&微服务>SCG网关篇五】Spring Cloud Gateway自定义PredicateFactory

    聊了以下问题:

    1. 为什么要有网关?网关的作用是什么?
    2. 网关的分类?
    3. 网关的技术选型?
    4. 使用网关时常用的灰度发布方式有哪些?
    5. Spring Cloud Gateway是什么?详细使用案例?
    6. Spring Cloud Gateway内置的11种PredicateFactory
    7. 如何自定义PredicateFactory

    本文接着聊Spring Cloud Gateway内置的Filter。

    PS:SpringCloud版本信息:

    <properties>
        <spring-boot.version>2.4.2spring-boot.version>
        <spring-cloud.version>2020.0.1spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1spring-cloud-alibaba.version>
    properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-dependenciesartifactId>
                <version>${spring-boot.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud-alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    二、GatewayFilter Factories

    Route filters 允许以某种方式修改传入HTTP的请求 或 传出HTTP的响应,其作用于特定的路由;Spring Cloud Gateway包括许多内置GatewayFilter工厂。

    在这里插入图片描述

    官方文档:https://docs.spring.io/spring-cloud-gateway/docs/3.0.1/reference/html/#gatewayfilter-factories

    官方一种一共给出了31中内嵌的Filter,我们这里抽几个比较常用的总结一下。

    1、请求/响应新增信息相关

    1)增加请求头参数(AddRequestHeaderGatewayFilterFactory)

    对所有请求增加请求头:entrance-header=gateway;

    spring:
      cloud:
        gateway:
          routes:
            - id: add_request_header_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - AddRequestHeader=entrance-header, gateway
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    添加动态请求头

    **此外:**添加的请求头参数可以根据Predicate的内容做动态填充,比如:

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: https://example.org
            predicates:
              - Path=/red/{segment}
            filters:
              - AddRequestHeader=entrance-header, Blue-{segment}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2)添加请求参数(AddRequestParameterGatewayFilterFactory)

    对所有请求增加entrance=gateway这个查询参数;

    spring:
      cloud:
        gateway:
          routes:
            - id: add_request_parameter_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - AddRequestParameter=entrance, gateway
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例请求如下:
    在这里插入图片描述

    添加动态请求参数

    此外: 添加的查询参数可以根据Predicate的内容做动态填充,比如:

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: https://example.org
            predicates:
              - Host: {segment}.myhost.org
            filters:
              - AddRequestParameter=foo, bar-{segment}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3)添加请求响应的请求头参数(AddResponseHeaderGatewayFilterFactory)

    对所有请求的响应增加entrance-header=gateway这个请求头;

    spring:
      cloud:
        gateway:
          routes:
          - id: add_response_header_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - AddResponseHeader=saint-response-header, handsome
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例验证如下:

    在这里插入图片描述

    2、请求/响应移除信息相关

    1)移除重复响应头(DedupeResponseHeaderGatewayFilterFactory)

    DedupeResponseHeader GatewayFilter factory有两个入参,一个是请求头的name,一个是可选参数:去重策略;

    去重策略有三种RETAIN_FIRST保留第一个(default)、RETAIN_LAST保留最后一个、RETAIN_FIRST RETAIN_UNIQUE 保留唯一。

    spring:
      cloud:
        gateway:
          routes:
            - id: add_request_parameter_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例为:移除重复的响应头信息 Access-Control-Allow-Credentials and Access-Control-Allow-Origin ,以防止网关CORS逻辑 和 下游逻辑都添加它们。

    2)移除响应头中的参数(RemoveResponseHeaderGatewayFilterFactory)

    移除响应头中的参数:X-Response-Foo;

    spring:
      cloud:
        gateway:
          routes:
            - id: add_request_parameter_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - RemoveResponseHeader=X-Response-Foo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3)移除请求头中的参数(RemoveRequestHeaderGatewayFilterFactory)

    移除请求头中的参数: X-Request-red

    spring:
      cloud:
        gateway:
          routes:
            - id: remove_request_header_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - RemoveRequestHeader=X-Request-red
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4)移除请求中的参数(RemoveRequestParameterGatewayFilterFactory)

    移除请求中的查询参数:red

    spring:
      cloud:
        gateway:
          routes:
            - id: remove_request_parameter_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - RemoveRequestParameter=red
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、请求/响应头信息替换

    此处和请求/响应新增信息一样,也支持动态参数配置。

    1)设置请求头信息(SetRequestHeaderGatewayFilterFactory)

    设置请求头,没有则新增,有则修改

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/simple-service/**
              filters:
                - SetRequestHeader=saint-request-header, saint-request
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2)设置响应头信息(SetResponseHeaderGatewayFilterFactory)

    设置响应头,没有则新增,有则修改

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - SetResponseHeader=saint-response-header, saint-response
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例验证:我们请求头中saint-request-header的值为:request,而发送请求后:

    在这里插入图片描述

    3)设置响应状态码(SetStatusGatewayFilterFactory)

    修改响应的状态码为特定值:可以是org.springframework.http.HttpStatus枚举,也可以直接写状态码(401、404等);

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/**
              filters:
                - SetStatus=401
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例中:无论哪种情况,响应的 HTTP 状态都会被设置为 401。

    4、请求路径层级相关

    1)移除请求层级(StripPrefixGatewayFilterFactory)

    StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/simple-service/**
              filters:
                - StripPrefix=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例中设置StripPrefix=2,则当通过网关向http://localhost:9999/gateway/simple-service/hello发出请求时,对simple-service的请求将类似于http://localhost:9001/hello

    2)增加请求层级(PrefixPathGatewayFilterFactory)

    StripPrefix参数表示在将请求发送到下游之前从请求中增加的路径个数。

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - PrefixPath=/saint
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例中设置PrefixPath=/saint,则当通过网关向http://localhost:9999/gateway/hello发出请求时,对simple-service的请求将类似于http://localhost:9001/saint/gateway/hello

    5、其他

    1)请求Host信息传递(PreserveHostHeaderGatewayFilterFactory)

    默认开启,在gateway转发请求前把原始请求的host头部带上,转发给目的服务;

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - PreserveHostHeader
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2)透传session信息(SaveSessionGatewayFilterFactory)

    SaveSession GatewayFilter factory迫使在向下游转发调用之前强制执行WebSession::save操作;当集成Spring Session时会将session放到Redis,来实现共享Session功能;

    如果gateway项目集成了Spring Session中的Spring Security框架,想要将安全验证信息转发到远程应用,那么这个配置是必须的。

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - SaveSession
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3)设置请求最大Size(RequestSizeGatewayFilterFactory)

    设置请求的最大Size,默认单位B,可以加 ‘KB’ 或 ‘MB’ 后缀;请求超过配置的maxSize,则会匹配路由失败

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - name: RequestSize
                  args:
                    maxSize: 5000000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4)重写路由转发地址(RewritePathGatewayFilterFactory)

    RewritePath GatewayFilter factory包含两个参数:正则表达形式的路径、正则表达形式的替代路径;其使用Java正则表达式来灵活地重写请求路径;

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - RewritePath=/gateway(?>/?.*), $\{segment}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    比如一个请求打向/gateway/hello,会被转发到/hello

    5)配置300系列状态码转发地址(RedirectToGatewayFilterFactory)

    RedirectTo GatewayFilter factory包含两个参数:状态码、和对应的转发地址url;

    状态码参数应该是300系列重定向HTTP代码:

    1. 301 Moved Permanently永久移动,请求的资源已被永久移动新位置,返回信息会包含URI,浏览器会自动定向到新地址,以后请求应该用新的URI代替;
    2. 302 Found 临时移动,与301类似,资源临时被移动,客户端应该继续使用原URI;
    3. 303 See Other查看其它地址,与301类似。使用GET和POST请求查看;
    4. 304 未修改,所请求资源未修改,服务器返回此状态吗时,不会返回任何资源;
    5. 305 Use proxy 使用代理,所请求资源必须通过代理;
    6. 306 Unused 已经废弃的HTTP状态码;
    7. 307 Temporary Redirect 临时重定向,与302类似,使用GET请求重定向;

    **转发地址url:**必须是有有效的URL,其是Response Header中Location属性的值,对于相对重定向,应该使用uri:no://op作为路由定义的uri。

    spring:
      cloud:
        gateway:
          routes:
            - id: simple_service_route
              uri: http://127.0.0.1:9001
              predicates:
                - Path=/gateway/**
              filters:
                - RedirectTo=302, https://www.baidu.com
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例的Response Header中将增加一个属性值为https://acme.org的Location属性。

    在这里插入图片描述

    6、给所有的Route设置DefaultFilter

    通过使用spring.cloud.gateway.default-filters,可以将一些Filter应用到所有的Route上;

    spring:
      cloud:
        gateway:
          default-filters:
          - AddResponseHeader=X-Response-Default-Red, Default-Blue
          - PrefixPath=/httpbin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、总结

    本文一共介绍了Gateway内置的18种常用的Filter,包括:针对单个路由的请求、响应、路由路径,针对所有Route的Default-Filters。

    后续文章我们聊一下Filter的高级用法,比如:限流、熔断、重试等。

  • 相关阅读:
    类和对象——默认成员函数
    使用Fiddler模拟网络
    小谈设计模式(29)—访问者模式
    Java基础——递归
    Hive学习笔记——数据类型及DDL数据定义
    路由进阶--编程式导航(在Vue路由中实现跳转,跳转传参)
    20min带你学习——HTTP协议、以及经典面试问题
    nvm管理不同版本nodejs
    Java基于微信小程序的电影交流平台
    大数据之就业岗位
  • 原文地址:https://blog.csdn.net/Saintmm/article/details/125776252