• Spring Cloud Gateway(十):网关过滤器工厂 GatewayFilterFactory


    本文基于 spring cloud gateway 2.0.1

    1、GatewayFilterFactory 简介

    路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。 路径过滤器的范围限定为特定路径。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。

    网关过滤器工厂接口有多个实现类,在每个 GatewayFilterFactory 实现类的 apply( T config) 方法里,都声明了一个实现 GatewayFilter 的内部类。

    内置的过滤器工厂一共有22个,分别位于 org.springframework.cloud.gateway.filter.factory及org.springframework.cloud.gateway.filter.factory.rewrite包中

    GatewayFilterFactory

    2、GatewayFilterFactory 分类

    过滤器 有 20 多个 实现 类, 包括 头部 过滤器、 路径 类 过滤器、 Hystrix 过滤器 和 变更 请求 URL 的 过滤器, 还有 参数 和 状态 码 等 其他 类型 的 过滤器。

    内置的过滤器工厂有22个实现类,包括 头部过滤器、路径过滤器、Hystrix 过滤器 、请求URL 变更过滤器,还有参数和状态码等其他类型的过滤器。根据过滤器工厂的用途来划分,可以分为以下几种:Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter和Hystrix

    在这里插入图片描述

    3、GatewayFilterFactory 源码

    由接口名称上的注解 @FunctionalInterface 可知,GatewayFilterFactory是一个函数式接口,其中 default 类型的方法 name 用来对过滤器进行标准化命名,apply 方法用于定义具体的过滤操作,泛型 C 是在各个实现类中的配置对象

    @FunctionalInterface
    public interface GatewayFilterFactory<C> extends ShortcutConfigurable, Configurable<C> {
    
    	String NAME_KEY = "name";
    	String VALUE_KEY = "value";
    
    	// useful for javadsl
    	default GatewayFilter apply(Consumer<C> consumer) {
    		C config = newConfig();
    		consumer.accept(config);
    		return apply(config);
    	}
    
    	default Class<C> getConfigClass() {
    		throw new UnsupportedOperationException("getConfigClass() not implemented");
    	}
    
    	@Override
    	default C newConfig() {
    		throw new UnsupportedOperationException("newConfig() not implemented");
    	}
    
    	GatewayFilter apply(C config);
    
    	default String name() {
    		//TODO: deal with proxys
    		return NameUtils.normalizeFilterFactoryName(getClass());
    	}
    
    	@Deprecated
    	default ServerHttpRequest.Builder mutate(ServerHttpRequest request) {
    		return request.mutate();
    	}
    }
    
    

    3.1、GatewayFilterFactory 抽象实现类

    在这里插入图片描述

    由 GatewayFilterFactory 类图可知,GatewayFilterFactory主要有三个抽象类:

    AbstractGatewayFilterFactory:
    
        HystrixGatewayFilterFactory
        ModifyRequestBodyGatewayFilterFactory
        ModifyResponseBodyGatewayFilterFactory
        PrefixPathGatewayFilterFactory
        PreserveHostHeaderGatewayFilterFactory
        RedirectToGatewayFilterFactory
        RemoveRequestHeaderGatewayFilterFactory
        RemoveResponseHeaderGatewayFilterFactory
        RequestRateLimiterGatewayFilterFactory
        RetryGatewayFilterFactory
        RewritePathGatewayFilterFactory
        SaveSessionGatewayFilterFactory
        SecureHeadersGatewayFilterFactory
        SetPathGatewayFilterFactory
        SetStatusGatewayFilterFactory
        StripPrefixGatewayFilterFactory
    
    AbstractNameValueGatewayFilterFactory(继承自AbstractGatewayFilterFactory)
    
        AddRequestHeaderGatewayFilterFactory
        AddRequestParameterGatewayFilterFactory
        AddResponseHeaderGatewayFilterFactory
        SetRequestHeaderGatewayFilterFactory
        SetResponseHeaderGatewayFilterFactory
    
    AbstractChangeRequestUriGatewayFilterFactory(继承自AbstractGatewayFilterFactory)
        
        RequestHeaderToRequestUriGatewayFilterFactory
    

    AbstractNameValueGatewayFilterFactory

    该抽象类用于提供通用的方法给键值对参数类型的网关过滤器,接收两个参数,如
    AddRequestHeader 这种类型的过滤器

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

    AbstractChangeRequestUriGatewayFilterFactory

    改变请求的 URI 过滤器,该过滤器通过方法 determineRequestUri( ServerWebExchange,T)实现改变请求URI的逻辑

    4、GatewayFilterFactory 实现类

    4.1、Header 类过滤器

    4.1.1、AddRequestHeaderGatewayFilterFactory

    增加请求的头部信息,并将头部传递到下游。

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

    这将为所有匹配请求的下游请求标头添加X-Request-Foo:Bar头。

    4.1.2、RemoveRequestHeaderGatewayFilterFactory

    在请求发送到下游之前,为匹配的请求移除设置的头部信息。

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://example.org
            filters:
            - RemoveResponseHeader=X-Response-Foo
    

    请求发送到下游之前删除X-Response-Foo头。

    4.1.3、AddResponseHeaderGatewayFilterFactory

    将会为匹配的请求增加响应头部,传递到下游的相应头部。

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

    这会将X-Response-Foo:Bar 头添加到所有匹配请求的下游响应标头中。

    4.1.4、RemoveResponseHeaderGatewayFilterFactory

    将相应结果返给客户端之前,将会移除设置的响应头部信息。

    spring:
      cloud:
        gateway:
          routes:
          - id: removeresponseheader_route
            uri: http://example.org
            filters:
            - RemoveResponseHeader=X-Response-Foo
    

    这将在响应返回到网关客户端之前从响应中删除X-Response-Foo标头。

    4.1.5、SetRequestHeaderGatewayFilterFactory

    当请求经过网关转发时,该过滤器将会用给定的名字替换所有的头部信息

    spring:
      cloud:
        gateway:
          routes:
          - id: setresponseheader_route
            uri: http://example.org
            filters:
            - SetRequestHeader=X-Response-Foo, Bar
    

    使用 X-Response-Foo:Bar替换请求头中对应属性的值

    4.1.6、SetResponseHeaderGatewayFilterFactory

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

    此GatewayFilter将替换具有给定名称的所有标头,而不是添加。 因此,如果下游服务器以X-Response-Foo:1234响应,则将替换为X-Response-Foo:Bar,这是网关客户端将接收的内容。

    4.1.7、PreserveHostHeaderGatewayFilterFactory

    PreserveHostHeader GatewayFilter Factory没有参数。 此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始主机头,而不是http客户端确定的主机头。

    spring:
      cloud:
        gateway:
          routes:
          - id: preserve_host_route
            uri: http://example.org
            filters:
            - PreserveHostHeader
    

    4.1.8、RequestHeaderToRequestUriGatewayFilterFactory

    spring:
      cloud:
        gateway:
          enabled: true
          discovery:
            locator:
              enabled: true
          routes:
          - id: request_header_to_request_uri_route
            uri: http://example.org
            filters:
            - RequestHeaderToRequestUri=X-New-Url
    
    

    当请求 http://example.org 时,会根据X-New-Url来进行新的url路由

    4.1.9、SecureHeadersGatewayFilterFactory

    当使用该过滤器时,会默认为请求头添加以下属性:

    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命名空间中设置相应的属性:

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

    关于这些请求头的含义可参考该文章:https://blog.appcanary.com/2017/http-security-headers.html

    4.2、Parameter 类过滤器

    4.2.1、AddRequestParameterGatewayFilterFactory

    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: http://example.org
            filters:
            - AddRequestParameter=foo, bar
    

    这会将foo = bar添加到下游请求的所有匹配请求的查询字符串中。

    4.3、Path 类过滤器

    4.3.1、PrefixPathGatewayFilterFactory

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://example.org
            filters:
            - PrefixPath=/mypath
    

    这将使/mypath前缀为所有匹配请求的路径。 所以对/hello的请求会被发送到/mypath / hello。

    4.3.2、RewritePathGatewayFilterFactory

    RewritePath网关过滤器工厂采用路径正则表达式参数和替换参数。 这使用Java正则表达式来灵活地重写请求路径。

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

    对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。 注意由于YAML规范,$ 替换为$。

    4.3.3、SetPathGatewayFilterFactory

    SetPath GatewayFilter Factory采用路径模板参数。 它提供了一种通过允许模板化路径段来操作请求路径的简单方法。 这使用了Spring Framework中的uri模板。 允许多个匹配的段。

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

    对于/ foo / bar的请求路径,这将在发出下游请求之前将路径设置为/ bar。

    4.3.4、StripPrefixGatewayFilterFactory

    StripPrefix网关过滤器工厂采用一个参数StripPrefix。 StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。

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

    当通过网关向/name/bar/foo发出请求时,对nameservice的请求将类似于http://nameservice/foo。

    4.4、Body 类过滤器

    4.4.1、ModifyRequestBodyGatewayFilterFactory

    用于修改请求头信息
    在这里插入图片描述

    它应该删除原始的Content-Length标头,并在需要时更新Content-Type。

    4.4.2、ModifyResponseBodyGatewayFilterFactory

    用于修改响应体信息

    4.5、Status 类过滤器

    4.5.1、SetStatusGatewayFilterFactory

    SetStatus GatewayFilter Factory采用单个状态参数。 它必须是有效的Spring HttpStatus。 它可以是整数值404或枚举NOT_FOUND的字符串表示。

    spring:
      cloud:
        gateway:
          routes:
          - id: setstatusstring_route
            uri: http://example.org
            filters:
            - SetStatus=BAD_REQUEST
          - id: setstatusint_route
            uri: http://example.org
            filters:
            - SetStatus=401
    

    在任何一种情况下,响应的HTTP状态都将设置为401。

    4.6、Session 类过滤器

    4.6.1、SaveSessionGatewayFilterFactory

    SaveSession GatewayFilter Factory在转发下游调用之前强制执行WebSession :: save操作。 当使用Spring Session与懒加载数据存储之类的东西时,这是特别有用的,并且需要确保在转发调用之前已保存会话状态。

    spring:
      cloud:
        gateway:
          routes:
          - id: save_session
            uri: http://example.org
            predicates:
            - Path=/foo/**
            filters:
            - SaveSession
    

    如果要将Spring Security与Spring Session集成,并且希望确保将安全性详细信息转发到远程进程,则这很关键。

    4.7、Redirect 类过滤器

    4.7.1、RedirectToGatewayFilterFactory

    RedirectTo GatewayFilter Factory采用status和url参数。 状态应该是300系列重定向http代码,例如301. url应该是有效的URL。 这将是Location标头的值。

    spring:
      cloud:
        gateway:
          routes:
          - id: prefixpath_route
            uri: http://example.org
            filters:
            - RedirectTo=302, http://acme.org
    

    将发送带有Location:http://acme.org 的请求头属性且状态302的请求,以执行重定向。

    4.8、Retry 类过滤器

    4.8.1、RetryGatewayFilterFactory

    该过滤器有三个参数:

    • retries: 重试次数
    • statuses: 应该重试的HTTP状态代码,使用org.springframework.http.HttpStatus表示
    • methods: 应该重试的HTTP方法,使用org.springframework.http.HttpMethod表示
    • series: 要重试的一系列状态代码,使用org.springframework.http.HttpStatus.Series表示
    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
    

    4.9、RateLimiter 类过滤器

    4.9.1、RequestRateLimiterGatewayFilterFactory

    RequestRateLimiter GatewayFilter Factory使用RateLimiter实现来确定是否允许当前请求继续。 如果不是,则返回HTTP 429 - Too Many Requests(默认情况下)的状态。

    此过滤器采用可选的keyResolver参数和特定于速率限制器的参数(参见下文)。

    keyResolver是一个实现KeyResolver接口的bean。 在配置中,使用SpEL按名称引用bean。 #{@ myKeyResolver}是一个引用名为myKeyResolver的bean的SpEL表达式。

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

    KeyResolver接口允许可插拔策略派生用于限制请求的密钥。 在未来的里程碑中,将会有一些KeyResolver实现。

    KeyResolver的默认实现是PrincipalNameKeyResolver,它从ServerWebExchange检索Principal并调用Principal.getName()。

    RequestRateLimiter不能通过“快捷方式”表示法进行配置。 以下示例无效

    application.properties
    
    # INVALID SHORTCUT CONFIGURATION
    spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
    

    4.10、Hystrix 类过滤器

    4.10.1、HystrixGatewayFilterFactory

    Hystrix是Netflix的一个库,它实现了断路器模式。 Hystrix GatewayFilter允许您将断路器引入网关路由,保护您的服务免受级联故障的影响,并允许您在下游故障时提供回退响应。

    要在项目中启用Hystrix GatewayFilters,请在Spring Cloud Netflix上添加对spring-cloud-starter-netflix-hystrix的依赖关系。

    Hystrix GatewayFilter Factory需要单个名称参数,该参数是HystrixCommand的名称。

    spring:
      cloud:
        gateway:
          routes:
          - id: hystrix_route
            uri: http://example.org
            filters:
            - Hystrix=myCommandName
    

    这将使用命令名myCommandName将剩余的过滤器包装在HystrixCommand中。

    Hystrix过滤器还可以接受可选的fallbackUri参数。 目前,仅支持forward:schemed URIs。 如果调用了回退,请求将被转发到与URI匹配的控制器。

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

    当调用Hystrix回调时,这将转发到/ incaseoffailureuset这个URI。 请注意,此示例还通过目标URI上的lb前缀演示(可选)Spring Cloud Netflix Ribbon负载平衡。

    主要目的是将fallbackUri用于网关应用程序内的内部控制器或处理程序。 但是,也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:

    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
    

    在此示例中,网关应用程序中没有回调端点或处理程序,但是,在http://localhost:9994下注册的另一个应用程序中有一个。

    如果请求被转发到回调地址时,Hystrix网关过滤器还会提供导致它的Throwable。 它作为ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR属性添加到ServerWebExchange中,可以在处理网关应用程序中的回退时使用该属性。

    对于外部控制器/处理程序方案,可以添加包含异常详细信息的标头。 您可以在FallbackHeaders GatewayFilter Factory部分中找到有关它的更多信息。

    Hystrix设置(例如超时)可以使用全局默认值配置,也可以使用应用程序属性逐个路径配置,如Hystrix wiki中所述。

    如果要为上面的示例路由设置5秒超时,将使用以下配置:

    application.yml
    
    hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
    
  • 相关阅读:
    分层图最短路(DP思想) BZOJ2662 [BeiJing wc2012]冻结
    动态规划 BZOJ1925 地精部落
    线性DP SPOJ Mobile Service
    线性DP codevs2185 最长公共上升子序列
    数位DP POJ3208 Apocalypse Someday
    线性DP POJ3666 Making the Grade
    杨氏矩阵 线性DP? POJ2279 Mr.Young's Picture Permutations
    tarjan强连通分量 洛谷P1262 间谍网络
    树链剖分 BZOJ3589 动态树
    二分图 BZOJ4554 [Tjoi2016&Heoi2016]游戏
  • 原文地址:https://www.cnblogs.com/liukaifeng/p/10055863.html
Copyright © 2020-2023  润新知