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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM