1. 程式人生 > >Spring Cloud之Gateway(二):閘道器過濾器

Spring Cloud之Gateway(二):閘道器過濾器

版本:2.0.2.RELEASE

連結:http://spring.io/projects/spring-cloud-gateway#overview

 

本章主要目錄如下:

Spring Cloud Gateway閘道器過濾器工廠是什麼?

 

本章主要內容如下:

Spring Cloud Gateway閘道器過濾器工廠是什麼?

路由過濾器允許以某種方式修改傳入的 HTTP 請求或輸出的 HTTP 響應。路由過濾器作用於特定路由。Spring Cloud Gateway 包含許多內建的 GatewayFilter 工廠。

 注意:有關如何使用下面的任何過濾器的更詳細的示例,請看單元測試。

 

  • AddRequestHeader 閘道器過濾器工廠

新增請求頭閘道器過濾器工廠可以在請求頭中新增一對鍵值對引數。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: add_request_header_route

        uri: http://example.org

        filters:

        - AddRequestHeader=X-Request-Foo, Bar

這將為所有匹配請求的下游請求頭部新增 X-Request-Foo:Bar。

 

  • AddRequestParameter 閘道器過濾器工廠

新增請求引數閘道器過濾器工廠可以在請求中新增一對請求引數的鍵值對。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: add_request_parameter_route

        uri: http://example.org

        filters:

        - AddRequestParameter=foo, bar

這會將 foo=bar 新增到所有匹配請求的下游請求的查詢字串中。

 

  • AddResponseHeader 閘道器過濾器工廠

新增響應頭閘道器過濾器工廠可以在響應頭中新增鍵值對。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: add_request_header_route

        uri: http://example.org

        filters:

        - AddResponseHeader=X-Response-Foo, Bar

這會將 X-Response-Foo:Bar 新增到所有匹配請求的下游響應頭部中。

 

  • Hystrix 閘道器過濾器工廠

Hystrix 是 Netflix 的一個庫,它實現了斷路器模式。Hystrix 閘道器過濾器允許您將斷路器引入到閘道器路由,保護您的服務免受級聯故障的影響,並允許您在下游故障時提供回退響應。

要在專案中啟用Hystrix 閘道器過濾器,請從Spring Cloud Netflix中新增spring-cloud-starter-netflix-hystrix依賴項。

Hystrix 閘道器過濾器需要一個名稱引數,該引數是HystrixCommand 的名稱。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: hystrix_route

        uri: http://example.org

        filters:

        - Hystrix=myCommandName

這將使用命令名稱 myCommandName 將剩餘的過濾器包裝在 HystrixCommand 中。

Hystrix過濾器還可以接受可選的fallbackUri引數。 目前,僅支援forward:schemed URIs。如果呼叫了回退,請求將被轉發到與 URI 匹配的控制器。

 

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

        - RewritePath=/consumingserviceendpoint, /backingserviceendpoint

當呼叫 Hystrix 回退時,將轉發到/incaseoffailureusethis URI。請注意, 此示例還通過目標 URI 上的 lb 字首演示(可選)Spring Cloud Netflix Ribbon 負載均衡。

Hystrix 設定(例如超時)可以使用全域性預設值配置,也可以使用應用程式屬性逐個路徑配置,如 Hystrix wiki 中所述。

 

要為上面的示例路由設定 5 秒超時,將使用以下配置:

application.yml

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

 

  • PrefixPath 閘道器過濾器工廠

PrefixPath 閘道器過濾器工廠使用的是一個簡單的 prefix 引數。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: prefixpath_route

        uri: http://example.org

        filters:

        - PrefixPath=/mypath

 

這將使/mypath 為所有匹配請求的路徑字首。所以,向/hello 請求將被髮送到/mypath/hello。

 

  • PreserveHostHeader 閘道器過濾器工廠

此閘道器過濾器工廠沒有引數。此過濾器設定路由過濾器將檢查的請求屬性,以確定是否應傳送原始主機頭,而不是 http 客戶端確定的主機頭。

application.yml

spring:

  cloud:

    gateway:

      routes:

      - id: preserve_host_route

        uri: http://example.org

        filters:

        - PreserveHostHeader

 

  • RequestRateLimiter 閘道器過濾器工廠

RequestRateLimiter 閘道器過濾器工廠使用 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 不能通過“shortcut”表示法進行配置。以下示例無效。

 

application.properties.

# INVALID SHORTCUT CONFIGURATION

spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

 

    -Redis 請求速率限制器

redis 實現基於 Stripe 完成的工作。它需要使用 spring-boot-starter-data-redis-reactive起步依賴。

使用的演算法是令牌桶演算法。

redis-rate-limiter.replenishRate:是您希望允許使用者每秒執行多少請求,而不會丟棄任何請求。這是令牌桶填充的速率。

redis-rate-limiter.burstCapacity:是使用者在一秒鐘內允許執行的最大請求數。這是令牌桶可以容納的令牌數。將此值設定為零將阻止所有請求。

通過在 replenishRate 和 burstCapacity 中設定相同的值來實現穩定的速率。通過將burstCapacity 設定為高於 replenishRate,可以允許臨時突發。在這種情況下,需要在這段突發時間之間允許速率限制器(根據 replenishRate),因為 2 個連續的突發將導致請求被丟棄(HTTP 429 - Too Many Requests)。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: requestratelimiter_route

        uri: http://example.org

        filters:

        - name: RequestRateLimiter

          args:

            redis-rate-limiter.replenishRate: 10

            redis-rate-limiter.burstCapacity: 20

 

Config.java.

@Bean

KeyResolver userKeyResolver() {

    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));

}

 

這定義了每個使用者的請求率限制是 10。允許突發 20,但下一秒只有 10 個請求可用。KeyResolver 是一個簡單的實現,它獲取使用者請求引數(注意:這不建議用於生產)。速率限制器也可以定義為實現 RateLimiter 介面的 bean。在配置中,使用 SpEL 按名稱引用 bean。#{@myRateLimiter}是一個引用名為 myRateLimiter 的 bean 的 SpEL 表示式。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: requestratelimiter_route

        uri: http://example.org

        filters:

        - name: RequestRateLimiter

          args:

            rate-limiter: "#{@myRateLimiter}"

            key-resolver: "#{@userKeyResolver}"

 

  • RedirectTo 閘道器過濾器工廠

重定向過濾器工廠接受一個狀態和一個 url 引數。該狀態是一個 300 系列重定向 http程式碼,如 301。url 應該是有效的 url。這將是 Location 頭部的值。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: prefixpath_route

        uri: http://example.org

        filters:

        - RedirectTo=302, http://acme.org

將使用 Location:http://acme.org 標頭髮送狀態 302 以執行重定向。

 

  • RemoveNonProxyHeaders 閘道器過濾器工廠

刪除非代理頭閘道器過濾器工廠從轉發的請求中刪除請求頭。被刪除的請求頭的預設列表來自 IETF。

預設刪除的請求頭是:

  Connection

  Keep-Alive

  Proxy-Authenticate

  Proxy-Authorization

  TE

  Trailer

  Transfer-Encoding

  Upgrade

要更改此設定,請將 spring.cloud.gateway.filter.remove-non-proxy-headers.headers屬性設定為要刪除的標頭名稱列表。

 

 

  • RemoveRequestHeader 閘道器過濾器工廠

刪除請求頭閘道器過濾器工廠需要一個名稱的引數,這個名稱引數是需要刪除的請求頭名。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: removerequestheader_route

        uri: http://example.org

        filters:

        - RemoveRequestHeader=X-Request-Foo

這將在向下遊傳送之前刪除 X-Request-Foo 請求頭。

 

  • RemoveResponseHeader 閘道器過濾器工廠

刪除響應頭閘道器過濾器工廠需要一個名稱的引數,這個名稱引數是需要刪除的響應頭名。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: removeresponseheader_route

        uri: http://example.org

        filters:

        - RemoveResponseHeader=X-Response-Foo

將在返回到閘道器客戶端之前從響應中刪除 X-Response-Foo 頭。

 

  • RewritePath 閘道器過濾器工廠

RewritePath 閘道器過濾器工廠採用路徑正則表示式引數和一個替換引數。使用 Java 正

則表示式靈活地重寫請求路徑。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: rewritepath_route

        uri: http://example.org

        predicates:

        - Path=/foo/**

        filters:

        - RewritePath=/foo/(?<segment>.*), /$\{segment}

對於/foo/bar 的請求路徑,將在生成下游請求之前設定路徑為/bar。注意,由於 YAML 規範,”$\” 被 “$” 替換。

 

  • SaveSession 閘道器過濾器工廠

SaveSession 閘道器過濾器工廠在轉發下游呼叫之前強制執行 WebSession::save 操作。當使用諸如 Spring Session 之類的帶有 lazy 資料儲存的東西時,這是特別有用的,並且需要在進行轉發呼叫之前確保會話狀態已被儲存。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: save_session

        uri: http://example.org

        predicates:

        - Path=/foo/**

        filters:

        - SaveSession

如果您正在將 Spring Security 和 Spring Session 整合,並且希望確保安全細節已經轉發到遠端程序,那麼這是至關重要的。

 

  • SecureHeaders 閘道器過濾器工廠

安全頭閘道器過濾器工廠在此部落格文章(https://blog.appcanary.com/2017/http-security-headers.html)的推薦中為響應添加了許多標題。

添加了以下標頭(預設值):

  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

 

  • SetPath 閘道器過濾器工廠

設定路徑閘道器過濾器工廠採用路徑模板引數。它提供了一種通過允許路徑的模板段來操作請求路徑的簡單方法。這使用了來自 Spring 框架的 URI 模板。允許多個匹配段。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: setpath_route

        uri: http://example.org

        predicates:

        - Path=/foo/{segment}

        filters:

        - SetPath=/{segment}

對於/foo/bar 的請求路徑,這將在進行下游請求之前將路徑設定為/bar。

 

  • SetResponseHeader 閘道器過濾器工廠

設定響應頭閘道器過濾器工廠需要引數名和引數的值的鍵值對引數。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: setresponseheader_route

        uri: http://example.org

        filters:

        - SetResponseHeader=X-Response-Foo, Bar

這個閘道器過濾器將給定的名稱對應響應頭的值替換掉原來請求響應頭的值,注意不是新增而是替換。 因此,如果下游伺服器用 X-Response-Foo:1234 響應,則將被X-Response-Foo:Bar 替代,閘道器客戶端將收到的響應頭為 X-Response-Foo:Bar 而不是X-Response-Foo:1234。

 

  • SetStatus 閘道器過濾器工廠

設定請求響應狀態閘道器過濾器工廠需要一個 status 引數。該引數值必須是一個有效的Spring HttpStatus。該值可以是整型 404 或者是表示列舉型別 NOT_FOUND 的字串。

application.yml

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。

 

  • StripPrefix 閘道器過濾器工廠

剝離字首閘道器過濾器工廠需要一個 parts 引數。parts 引數表明在將請求傳送到下游之前從請求中剝離的路徑中的元素數量。

application.yml.

spring:

  cloud:

    gateway:

      routes:

      - id: nameRoot

        uri: http://nameservice

        predicates:

        - Path=/name/**

        filters:

        - StripPrefix=2

當通過閘道器向/name/bar/foo 發出請求時,對nameservice 的請求將類似於http://nameservice/foo

 

  • Retry 閘道器過濾器工廠

重試閘道器過濾器工廠需要 retries, statuses, methods 和 series 作為引數。

  retries:將會嘗試的重試次數

  statuses:將會重試的 HTTP 狀態程式碼,用org.springframework.http.HttpStatus

表示。

  methods:將會重試的 HTTP 方法,使用 org.springframework.http.HttpMethod

表示。

  series:要重試的一系列狀態程式碼,用 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

注意:當使用帶有forward:字首URL 的重試過濾器時,應仔細編寫目標端點,以便在出現錯誤時不會執行任何可能導致響應傳送到客戶端並提交的操作。例如,如果目標端點是帶註釋的控制器,則目標控制器方法不應返回ResponseEntity錯誤狀態程式碼。相反,它應該丟擲一個Exception或發出錯誤訊號,例如通過Mono.error(ex)返回值,重試過濾器可以配置為通過重試來處理。這裡是不是可以理解使用前向協議的 URI 不支援使用重試過濾器。

 

//2.1.0.M3版本新增該過濾器,在這裡我們也做一下了解

  • RequestSize 閘道器過濾器工廠

當請求大小大於允許的限制時,RequestSize 閘道器過濾器可以限制請求到達下游服務。過濾器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

當請求因大小而被拒絕時,RequestSize 閘道器過濾器將響應狀態設定為 413 Payload Too Large(有效負載太大),並附加標頭 errorMessage。以下是此類 errorMessage 的示例。

errorMessage : 請求大小大於允許的限制。請求大小為 6.0 MB,允許的限制為 5.0 MB。

注意:如果未在路由定義中提供過濾器引數,則預設請求大小將設定為5 MB。

 

如有疑惑,關注公眾號獲取更多內容,下一章將一起討論全域性過濾器。