• Gateway GatewayFilter Factories


    GatewayFilter Factories

    Route filters可以通过一些方式修改HTTP请求的输入和输出,针对某些特殊的场景,Spring Cloud Gateway已经内置了很多不同功能的GatewayFilter Factories。

    下面就来通过例子逐一讲解这些GatewayFilter Factories。

    1. AddRequestHeader GatewayFilter Factory

    AddRequestHeader GatewayFilter Factory通过名称我们可以快速的明白这个过滤器工厂的作用,就是添加请求头。通过配置name和value可以增加请求的header。
    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: http://www.google.com
            filters:
            - AddRequestHeader=X-Request-Foo, Bar

    上面的配置,我们对www.google.com这个服务的路由配置了AddRequestHeader,增加了一个名称为X-Request-Foo,值是Bar的请求头。

    2. AddRequestParameter GatewayFilter Factory

    AddRequestParameter GatewayFilter Factory通过配置name和value可以增加请求的参数。
    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: http://www.google.com
            filters:
            - AddRequestParameter=foo, bar

    对匹配的请求,会额外添加foo=bar的请求参数。

    3. AddResponseHeader GatewayFilter Factory

    AddResponseHeader GatewayFilter Factory通过配置name和value可以增加响应的header。
    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: http://www.google.com
            filters:
            - AddResponseHeader=X-Response-Foo, Bar

    对匹配的请求,响应返回时会额外添加X-Response-Foo:Bar的header返回。

    4. Hystrix GatewayFilter Factory

    Hystrix是Netflix实现的断路器模式工具包,The Hystrix GatewayFilter就是将断路器使用在gateway的路由上,目的是保护你的服务避免级联故障,以及在下游失败时可以降级返回。

    项目里面引入spring-cloud-starter-netflix-hystrix依赖,并提供HystrixCommand的名字,即可生效Hystrix GatewayFilter。
    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: hystrix_route
            uri: http://www.google.com
            filters:
            - Hystrix=myCommandName

    Hystrix过滤器也是通过配置可以参数fallbackUri,来支持路由熔断后的降级处理,降级后,请求会跳过fallbackUri配置的路径,目前只支持forward:的URI协议。那么剩下的过滤器,就会包装在名为myCommandName的HystrixCommand中运行。

    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: hystrix_route
            uri: lb://backing-service:8088
            predicates:
            - Path=/consumingserviceendpoint
            filters:
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/incaseoffailureusethis

    整个流程其实是用fallbackUri将请求跳转到gateway内部的controller或者handler,然而也可以通过以下的方式将请求转发到外部的服务:当Hystrix降级后就会将请求转发到/incaseoffailureusethis

    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: ingredients
            uri: lb://ingredients
            predicates:
            - Path=//ingredients/**
            filters:
            - name: Hystrix
              args:
                name: fetchIngredients
                fallbackUri: forward:/fallback
          - id: ingredients-fallback
            uri: http://localhost:9994
            predicates:
            - Path=/fallback

    Hystrix Gateway filter在转发降级请求时,会将造成降级的异常设置在ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR属性中,在处理降级时也可以用到。以上的例子,gateway降级后就会将请求转发到http://localhost:9994

    比如下一节讲到的FallbackHeaders GatewayFilter Factory,就会通过上面的方式拿到异常信息,设置到降级转发请求的header上,来告知降级下游异常信息。

    通过下面配置可以设置Hystrix的全局超时信息:
    application.yml:

    hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000

    5. FallbackHeaders GatewayFilter Factory

    FallbackHeaders GatewayFilter Factory可以将Hystrix执行的异常信息添加到外部请求的fallbackUriheader上。

    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: ingredients
            uri: lb://ingredients
            predicates:
            - Path=//ingredients/**
            filters:
            - name: Hystrix
              args:
                name: fetchIngredients
                fallbackUri: forward:/fallback
          - id: ingredients-fallback
            uri: http://localhost:9994
            predicates:
            - Path=/fallback
            filters:
            - name: FallbackHeaders
              args:
                executionExceptionTypeHeaderName: Test-Header

    你也可以使用默认的header,也可以像上面一下配置修改header的名字:在这个例子中,当请求lb://ingredients降级后,FallbackHeaders filter会将HystrixCommand的异常信息,通过Test-Header带给http://localhost:9994服务。

    • executionExceptionTypeHeaderName ("Execution-Exception-Type")
    • executionExceptionMessageHeaderName ("Execution-Exception-Message")
    • rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
    • rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")

    6. PrefixPath GatewayFilter Factory

    The PrefixPath GatewayFilter Factor通过设置prefix参数来路径前缀。
    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://www.google.com
            filters:
            - PrefixPath=/mypath

    如果一个请求是/hello,通过上面路由,就会将请求修改为/mypath/hello

    7. PreserveHostHeader GatewayFilter Factory

    PreserveHostHeader GatewayFilter Factory会保留原始请求的host头信息,并原封不动的转发出去,而不是被gateway的http客户端重置。

    application.yml:

    spring:
      cloud:
        gateway:
          routes:
          - id: preserve_host_route
            uri: http://www.google.com
            filters:
            - PreserveHostHeader

    8. RequestRateLimiter GatewayFilter Factory(限流)

    RequestRateLimiter GatewayFilter Factory使用RateLimiter来决定当前请求是否允许通过,如果不允许,则默认返回状态码HTTP 429 - Too Many Requests

    RequestRateLimiter GatewayFilter可以使用一个可选参数keyResolver来做速率限制。

    keyResolverKeyResolver接口的一个实现bean,在配置里面,通过SpEL表达式#{@myKeyResolver}来管理bean的名字myKeyResolver

    KeyResolver.java.

    public interface KeyResolver {
        Mono<String> resolve(ServerWebExchange exchange);
    }

    KeyResolver默认实现是PrincipalNameKeyResolver,通过ServerWebExchange中获取Principal,并以Principal.getName()作为限流的key。KeyResolver接口允许你使用不同的策略来得出限制请求的key,未来,官方也会推出一些KeyResolver的不同实现。

    如果KeyResolver拿不到key,请求默认都会被限制,你也可以自己配置spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key:是否允许空key,spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code :空key时返回的状态码。

    RequestRateLimiter不支持捷径配置,如下面的配置是非法的

    application.properties.

    # INVALID SHORTCUT CONFIGURATION
    spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
    基于 Stripe的redis实现方案,依赖spring-boot-starter-data-redis-reactiveSpring Boot starter,使用的是令牌桶算法

    8.1 Redis RateLimiter

    redis-rate-limiter.replenishRate配置的是每秒允许通过的请求数,其实就是令牌桶的填充速率。

    redis-rate-limiter.burstCapacity配置的是一秒内最大的请求数,其实就是令牌桶的最大容量,如果设置为0,则会阻塞所有请求。

    所以可以通过设置相同的replenishRateburstCapacity来实现匀速的速率控制,通过设置burstCapacity大于replenishRate来允许系统流量瞬间突发,但是对于这种情况,突发周期为burstCapacity / replenishRate秒,如果周期内有两次请求突发的情况,则第二次会有部分请求丢失,返回HTTP 429 - Too Many Requests

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: requestratelimiter_route
            uri: http://www.google.com
            filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
    @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }

    Config.java.

    上面定义了每个用户每秒10个请求的速率限制,允许20的突发流量,突发完,下一秒只允许10个请求通过了,KeyResolver定义了通过请求获取请求参数user作为key。

    你也可以实现RateLimiter接口自定义自己的请求速率限制器,在配置文件中使用SpEL表达式配置对应的bean的名字即可。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: requestratelimiter_route
            uri: http://www.google.com
            filters:
            - name: RequestRateLimiter
              args:
                rate-limiter: "#{@myRateLimiter}"
                key-resolver: "#{@userKeyResolver}"

    9. RedirectTo GatewayFilter Factory

    RedirectTo GatewayFilter Factory使用statusurl两个参数,其中status必须是300系列的HTTP状态码,url则是跳转的地址,会放在响应的Location的header中(http协议中转跳的header)。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://www.google.cn
            filters:
            - RedirectTo=302, http://www.edjdhbb.com

    上面路由会执行302重定向到http://www.edjdhbb.com。

    10. RemoveNonProxyHeaders GatewayFilter Factory

    RemoveNonProxyHeaders GatewayFilter Factory转发请求是会根据IETF的定义,默认会移除下列的http头信息:

    • Connection
    • Keep-Alive
    • Proxy-Authenticate
    • Proxy-Authorization
    • TE
    • Trailer
    • Transfer-Encoding
    • Upgrade

    你也可以通过配置spring.cloud.gateway.filter.remove-non-proxy-headers.headers来更改需要移除的header列表。

    11. RemoveRequestHeader GatewayFilter Factory

    RemoveRequestHeader GatewayFilter Factory配置header的name,即可以移除请求的header。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: removerequestheader_route
            uri: http://www.google.com
            filters:
            - RemoveRequestHeader=X-Request-Foo

    上面路由在发送请求给下游时,会将请求中的X-Request-Foo头信息去掉。

    12. RemoveResponseHeader GatewayFilter Factory

    RemoveResponseHeader GatewayFilter Factory通过配置header的name,会在响应返回时移除header。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://www.google.com
            filters:
            - RemoveResponseHeader=X-Response-Foo

    上面路由会在响应返回给gateway的客户端时,将X-Response-Foo响应头信息去掉。

    13. RewritePath GatewayFilter Factory

    RewritePath GatewayFilter Factory使用路径regexp和替换路径replacement两个参数做路径重写,两个都可以灵活地使用java的正则表达式。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: rewritepath_route
            uri: http://www.google.com
            predicates:
            - Path=/foo/**
            filters:
            - RewritePath=/foo/(?<segment>.*), /${segment}

    注:在YAML 的格式中使用$来代替$对于上面的例子,如果请求的路径是/foo/bar,则gateway会将请求路径改为/bar发送给下游。

    14. RewriteResponseHeader GatewayFilter Factory

    RewriteResponseHeader GatewayFilter Factory的作用是修改响应返回的header内容,需要配置响应返回的header的name,匹配规则regexp和替换词replacement,也是支持java的正则表达式。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: rewriteresponseheader_route
            uri: http://www.google.com
            filters:
            - RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***

    举个例子,对于上面的filter,如果响应的headerX-Response-Foo的内容是/42?user=ford&password=omg!what&flag=true,这个内容会修改为/42?user=ford&password=***&flag=true

    15. SaveSession GatewayFilter Factory

    SaveSession GatewayFilter Factory会在请求下游时强制执行WebSession::save方法,用在那种像Spring Session延迟数据存储的,并在请求转发前确保session状态保存情况。

    application.yml.

    spring:
      cloud:
        gateway:
          routes:
          - id: save_session
            uri: http://www.google.com
            predicates:
            - Path=/foo/**
            filters:
            - SaveSession

    如果你将Spring SecutirySpring Session集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。

    16. SecureHeaders GatewayFilter Factory

    SecureHeaders GatewayFilter Factory会添加在返回响应中一系列安全作用的header,至于为什么,英文好的可以看一下这篇博客

    默认会添加这些头信息和默认内容:

    • X-Xss-Protection:1; mode=block
    • Strict-Transport-Security:max-age=631138519
    • X-Frame-Options:DENY
    • X-Content-Type-Options:nosniff
    • Referrer-Policy:no-referrer
    • Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
    • X-Download-Options:noopen
    • X-Permitted-Cross-Domain-Policies:none

    如果你想修改这些头信息的默认内容,可以在配置文件中添加下面的配置:

    前缀:spring.cloud.gateway.filter.secure-headers

    上面的header对应的后缀:

    • xss-protection-header
    • strict-transport-security
    • frame-options
    • content-type-options
    • referrer-policy
    • content-security-policy
    • download-options
    • permitted-cross-domain-policies

    前后缀接起来即可,如:spring.cloud.gateway.filter.secure-headers.xss-protection-header

    17. SetPath GatewayFilter Factory

    SetPath GatewayFilter Factory采用路径template参数,通过请求路径的片段的模板化,来达到操作修改路径的目的,运行多个路径片段模板化。

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: setpath_route
    uri: http://www.google.com
    predicates:
    - Path=/foo/{segment}
    filters:
    - SetPath=/{segment}

    对于上面的例子,如果路径是/foo/bar,则对于下游的请求路径会修改为/bar

    18. SetResponseHeader GatewayFilter Factory

    SetResponseHeader GatewayFilter Factory通过设置namevalue来替换响应对于的header。

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: setresponseheader_route
    uri: http://www.google.com
    filters:
    - SetResponseHeader=X-Response-Foo, Bar

    对于上面的例子,如果下游的返回带有头信息为X-Response-Foo:1234,则会gateway会替换为X-Response-Foo:Bar,在返回给客户端。

    19. SetStatus GatewayFilter Factory

    SetStatus GatewayFilter Factory通过配置有效的Spring HttpStatus枚举参数,可以是类似于404的这些数字,也可以是枚举的name字符串,来修改响应的返回码。

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: setstatusstring_route
    uri: http://www.google.com
    filters:
    - SetStatus=BAD_REQUEST
    - id: setstatusint_route
    uri: http://www.google.com
    filters:
    - SetStatus=401

    上面例子中,两种路由都会将响应的状态码设置为401。

    20. StripPrefix GatewayFilter Factory

    StripPrefix GatewayFilter Factory通过配置parts来表示截断路径前缀的数量。

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: nameRoot
    uri: http://nameservice
    predicates:
    - Path=/name/**
    filters:
    - StripPrefix=2

    如上面例子中,如果请求的路径为/name/bar/foo,则路径会修改为/foo,即将路径的两个前缀去掉了。

    21. Retry GatewayFilter Factory

    Retry GatewayFilter Factory可以配置针对不同的响应做请求重试,可以配置如下参数:

    • retries: 重试次数
    • statuses: 需要重试的状态码,需要根据枚举 org.springframework.http.HttpStatus来配置
    • methods: 需要重试的请求方法,需要根据枚举org.springframework.http.HttpMethod来配置
    • series: HTTP状态码系列,详情见枚举org.springframework.http.HttpStatus.Series

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: retry_test
    uri: http://localhost:8080/flakey
    predicates:
    - Host=*.retry.com
    filters:
    - name: Retry
    args:
    retries: 3
    statuses: BAD_GATEWAY

    上面例子,当下游服务返回502状态码时,gateway会重试3次。

    22. RequestSize GatewayFilter Factory

    RequestSize GatewayFilter Factory会限制客户端请求包的大小,通过参数RequestSize来配置最大上传大小,单位字节。

    application.yml.

    spring:
    cloud:
    gateway:
    routes:
    - id: request_size_route
    uri: http://localhost:8080/upload
    predicates:
    - Path=/upload
    filters:
    - name: RequestSize
    args:
    maxSize: 5000000

    如果请求大小超过5000kb限制,则会返回状态码413 Payload Too Large

    如果不设置这个filter,默认限制5M的请求大小。

    23. Modify Request Body GatewayFilter Factory

    官方说这个filter目前只是beta版本,API以后可能会修改。

    Modify Request Body GatewayFilter Factory可以修改请求体内容,这个只能通过java来配置。

    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
    .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
    .filters(f -> f.prefixPath("/httpbin")
    .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
    (exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
    .build();
    }

    static class Hello {
    String message;

    public Hello() { }

    public Hello(String message) {
    this.message = message;
    }

    public String getMessage() {
    return message;
    }

    public void setMessage(String message) {
    this.message = message;
    }
    }

    24. Modify Response Body GatewayFilter Factory

    官方说这个filter目前只是beta版本,API以后可能会修改。

    Modify Response Body GatewayFilter Factory用于修改响应返回的内容,同样只能通过java配置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
    .route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
    .filters(f -> f.prefixPath("/httpbin")
    .modifyResponseBody(String.class, String.class,
    (exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)
    .build();
    }

    转自:https://www.edjdhbb.com/2019/01/06/spring%20cloud%20gateway%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8B2%E2%80%94%E2%80%94GatewayFilter_%E4%B8%8B%E7%AF%87/

  • 相关阅读:
    20135315宋宸宁信息安全系统设计基础期末总结
    信息安全系统设计基础第十四周学习总结
    树莓派之web服务器搭建
    读书笔记——《图解TCP/IP》(2/4)
    信息安全系统设计基础第十三周学习总结
    读书笔记——《图解TCP/IP》(1/4)
    读书笔记——《暗时间》汇总
    信息安全系统设计基础第十二周学习总结
    20135315 宋宸宁 、20135333 苏正生——实验3
    读书笔记——《暗时间》(2/2)
  • 原文地址:https://www.cnblogs.com/duanxz/p/14766191.html
Copyright © 2020-2023  润新知