springcloud-gateway 網關組件中文文檔

? ? Spring Cloud網關

Greenwich SR5

該項目提供了一個基于Spring生態系統的API網關,其中包括:Spring 5,Spring Boot 2和項目Reactor。Spring Cloud網關的目的是提供一種簡單而有效的方法來路由到API,并向它們提供跨領域的關注,例如:安全性,監視/度量和彈性。

? ? 如何包括Spring Cloud網關

要將Spring Cloud網關包含在項目中,請將該啟動器與組org.springframework.cloud和工件ID?spring-cloud-starter-gateway一起使用。有關?使用當前Spring Cloud版本Train設置構建系統的詳細信息,請參見Spring Cloud項目頁面。

如果包括啟動器,但由于某種原因,您不希望啟用網關,請設置spring.cloud.gateway.enabled=false

[重要]

重要

Spring Cloud網關基于Spring Boot 2.x,?Spring WebFlux和項目Reactor?構建。因此,使用Spring Cloud網關時,許多熟悉的同步庫(例如,Spring Data和Spring Security)和模式可能不適用。如果您不熟悉這些項目,建議您在使用Spring Cloud Gateway之前,先閱讀它們的文檔以熟悉一些新概念。

[重要]

重要

Spring Cloud網關需要Spring Boot和Spring Webflux提供的Netty運行時。它不能在傳統的Servlet容器中或作為WAR構建。

111.詞匯表

  • 路由:路由網關的基本構建塊。它由ID,目標URI,謂詞集合和過濾器集合定義。如果聚合謂詞為true,則匹配路由。
  • 謂詞:這是?Java 8 Function謂詞。輸入類型為?Spring Framework?ServerWebExchange。這使開發人員可以匹配HTTP請求中的任何內容,例如標頭或參數。
  • 過濾器:這些是使用特定工廠構造的實例?Spring Framework?GatewayFilter。在此,可以在發送下游請求之前或之后修改請求和響應。

112.工作原理

Spring Cloud網關圖

客戶端向Spring Cloud網關發出請求。如果網關處理程序映射確定請求與路由匹配,則將其發送到網關Web處理程序。該處理程序運行通過特定于請求的篩選器鏈發送請求。篩選器由虛線分隔的原因是,篩選器可以在發送代理請求之前或之后執行邏輯。執行所有“前置”過濾器邏輯,然后發出代理請求。發出代理請求后,將執行“后”過濾器邏輯。

[注意]

在沒有端口的路由中定義的URI將分別將HTTP和HTTPS URI的默認端口分別設置為80和443。

113.配置路由謂詞工廠和網關過濾工廠

有兩種配置謂詞和過濾器的方法:快捷方式和完全擴展的參數。下面的大多數示例都使用快捷方式。

名稱和自變量名稱將在第一部分或每部分的兩個部分中以code的形式列出。參數通常按快捷方式配置所需的順序列出。

113.1快捷方式配置

快捷方式配置由過濾器名稱識別,后跟等號(=),后跟由逗號分隔的參數值(,)。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: after_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Cookie</span>=mycookie,mycookievalue</span></span></span>

先前的示例使用兩個參數定義了Cookie?Route Predicate Factory,即cookie名稱mycookie和與mycookievalue相匹配的值。

113.2完全展開的參數

完全擴展的參數看起來更像帶有名稱/值對的標準Yaml配置。通常,將有一個name鍵和一個args鍵。args鍵是用于配置謂詞或過濾器的鍵值對的映射。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: after_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - name</span>: Cookie
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            name</span>: mycookie
<span style="color:#7f007f">            regexp</span>: mycookievalue</span></span></span>

這是上面顯示的Cookie謂詞的快捷方式配置的完整配置。

114.路由謂詞工廠

Spring Cloud網關將路由匹配為Spring WebFlux?HandlerMapping基礎結構的一部分。Spring Cloud網關包括許多內置的Route Predicate工廠。所有這些謂詞都與HTTP請求的不同屬性匹配。多個路由謂詞工廠可以合并,也可以通過邏輯and合并。

114.1路由謂詞工廠之后

After路由謂詞工廠采用一個參數,即datetime(這是Java?ZonedDateTime)。該謂詞匹配在當前日期時間之后發生的請求。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: after_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - After</span>=2017-01-20T17:42:47.789-07:00[America/Denver<span style="color:#7f0055"><strong>]</strong></span></span></span></span>

該路線與2017年1月20日17:42山區時間(丹佛)之后的所有請求匹配。

114.2路線謂詞工廠之前

Before路由謂詞工廠采用一個參數datetime(它是Java?ZonedDateTime)。該謂詞匹配當前日期時間之前發生的請求。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: before_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Before</span>=2017-01-20T17:42:47.789-07:00[America/Denver<span style="color:#7f0055"><strong>]</strong></span></span></span></span>

該路線與2017年1月20日17:42山區時間(丹佛)之前的所有請求匹配。

114.3路由謂詞工廠之間

Between路由謂詞工廠采用兩個參數datetime1datetime2,它們是Java?ZonedDateTime對象。該謂詞匹配在datetime1之后和datetime2之前發生的請求。datetime2參數必須在datetime1之后。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: between_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Between</span>=2017-01-20T17:42:47.789-07:00[America/Denver]<span style="color:#7f0055"><strong>,</strong></span> 2017-01-21T17:42:47.789-07:00[America/Denver<span style="color:#7f0055"><strong>]</strong></span></span></span></span>

該路線與2017年1月20日山區時間(丹佛)之后和2017年1月21日17:42山區時間(丹佛)之后的所有請求匹配。這對于維護時段可能很有用。

114.4 Cookie路線謂詞工廠

Cookie?Route Predicate Factory采用兩個參數,即cookie?nameregexp(這是Java正則表達式)。該謂詞匹配具有給定名稱的cookie,并且值匹配正則表達式。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: cookie_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Cookie</span>=chocolate<span style="color:#7f0055"><strong>,</strong></span> ch.p</span></span></span>

此路由與請求匹配,具有一個名為chocolate的cookie,該cookie的值與ch.p正則表達式匹配。

114.5標頭路由謂詞工廠

Header?Route Predicate Factory具有兩個參數,標頭nameregexp(這是Java正則表達式)。該謂詞與具有給定名稱的標頭匹配,并且值與正則表達式匹配。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Header</span>=X-Request-Id<span style="color:#7f0055"><strong>,</strong></span> \d+</span></span></span>

如果請求具有名為X-Request-Id的標頭,且其值與\d+正則表達式匹配(具有一個或多個數字的值),則此路由匹配。

114.6主機路由謂詞工廠

Host?Route Predicate Factory采用一個參數:主機名patterns的列表。模式是Ant樣式的模式,以.作為分隔符。該謂詞與匹配模式的Host頭匹配。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: host_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>=**.somehost.org,**.anotherhost.org</span></span></span>

還支持URI模板變量,例如{sub}.myhost.org

如果請求的Host標頭的值為www.somehost.orgbeta.somehost.orgwww.anotherhost.org,則此路由將匹配。

該謂詞提取URI模板變量(如上例中定義的sub)作為名稱和值的映射,并使用在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定義的鍵將其放置在ServerWebExchange.getAttributes()中。這些值可供GatewayFilter工廠使用。

114.7方法路線謂詞工廠

Method路由謂詞工廠采用一個methods參數,該參數是一個或多個要匹配的HTTP方法。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: method_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Method</span>=GET,POST</span></span></span>

如果請求方法是GETPOST,則此路由將匹配。

114.8路徑路線謂詞工廠

Path路由謂詞工廠采用兩個參數:Spring?PathMatcher?patterns的列表和matchOptionalTrailingSeparator的可選標志。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: host_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/foo/{segment},/bar/{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

如果請求路徑為例如/foo/1/foo/bar/bar/baz,則此路由將匹配。

該謂詞提取URI模板變量(如以上示例中定義的segment)作為名稱和值的映射,并使用在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定義的鍵將其放置在ServerWebExchange.getAttributes()中。這些值可供GatewayFilter工廠使用。

可以使用實用程序方法來簡化對這些變量的訪問。

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);String segment = uriVariables.get(<span style="color:#2a00ff">"segment"</span>);</span></span></span>

114.9查詢路由謂詞工廠

Query?Route Predicate Factory采用兩個參數:必需的param和可選的regexp(這是Java正則表達式)。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: query_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Query</span>=baz</span></span></span>

如果請求包含baz查詢參數,則此路由將匹配。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: query_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Query</span>=foo<span style="color:#7f0055"><strong>,</strong></span> ba.</span></span></span>

如果請求包含一個foo查詢參數,其值與ba.正則表達式匹配,則此路由將匹配,因此barbaz將匹配。

114.10 RemoteAddr路由謂詞工廠

RemoteAddr路由謂詞工廠采用sources的列表(最小大小1),它是CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,?16是子網掩碼)。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: remoteaddr_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - RemoteAddr</span>=192.168.1.1/24</span></span></span>

如果請求的遠程地址為192.168.1.10,則此路由將匹配。

114.11重量路線謂詞工廠

Weight?Route Predicate Factory接受兩個參數groupweight(一個int)。權重是按組計算的。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: weight_high
<span style="color:#7f007f">        uri</span>: https://weighthigh.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Weight</span>=group1<span style="color:#7f0055"><strong>,</strong></span> 8
<span style="color:#7f007f">      - id</span>: weight_low
<span style="color:#7f007f">        uri</span>: https://weightlow.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Weight</span>=group1<span style="color:#7f0055"><strong>,</strong></span> 2</span></span></span>

此路由會將約80%的流量轉發到https://weighthigh.org,并將約20%的流量轉發到https://weighlow.org

114.11.1修改解析遠程地址的方式

默認情況下,RemoteAddr路由謂詞工廠使用傳入請求中的遠程地址。如果Spring Cloud網關位于代理層后面,則此地址可能與實際的客戶端IP地址不匹配。

您可以通過設置自定義RemoteAddressResolver來自定義解析遠程地址的方式。Spring Cloud網關帶有一個基于X-Forwarded-For標頭?XForwardedRemoteAddressResolver的非默認遠程地址解析器。

XForwardedRemoteAddressResolver有兩個靜態構造方法,它們采用不同的安全性方法:

XForwardedRemoteAddressResolver::trustAll返回一個RemoteAddressResolver,該地址始終使用在X-Forwarded-For標頭中找到的第一個IP地址。這種方法容易受到欺騙,因為惡意客戶端可能會為X-Forwarded-For設置一個初始值,該初始值將被解析程序接受。

XForwardedRemoteAddressResolver::maxTrustedIndex獲取一個索引,該索引與在Spring Cloud網關前面運行的受信任基礎結構的數量相關。例如,如果Spring Cloud網關只能通過HAProxy訪問,則應使用值1。如果在訪問Spring Cloud網關之前需要兩跳可信基礎結構,則應使用值2。

給定以下標頭值:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3</span></span></span>

下面的maxTrustedIndex值將產生以下遠程地址。

maxTrustedIndex結果

[Integer.MIN_VALUE,0]

(invalid,?IllegalArgumentException?during initialization)

1

0.0.0.3

2

0.0.0.2

3

0.0.0.1

[4,?Integer.MAX_VALUE]

0.0.0.1

使用Java配置:

GatewayConfig.java

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">RemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);....route(<span style="color:#2a00ff">"direct-route"</span>,r -> r.remoteAddr(<span style="color:#2a00ff">"10.1.1.1"</span>, <span style="color:#2a00ff">"10.10.1.1/24"</span>).uri(<span style="color:#2a00ff">"https://downstream1"</span>)
.route(<span style="color:#2a00ff">"proxied-route"</span>,r -> r.remoteAddr(resolver,  <span style="color:#2a00ff">"10.10.1.1"</span>, <span style="color:#2a00ff">"10.10.1.1/24"</span>).uri(<span style="color:#2a00ff">"https://downstream2"</span>)
)</span></span></span>

115.網關過濾器工廠

路由過濾器允許以某種方式修改傳入的HTTP請求或傳出的HTTP響應。路由過濾器適用于特定路由。Spring Cloud網關包括許多內置的GatewayFilter工廠。

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

115.1 AddRequestHeader GatewayFilter工廠

AddRequestHeader?GatewayFilter工廠采用namevalue參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_request_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddRequestHeader</span>=X-Request-Foo<span style="color:#7f0055"><strong>,</strong></span> Bar</span></span></span>

這會將X-Request-Foo:Bar標頭添加到所有匹配請求的下游請求標頭中。

AddRequestHeader知道用于匹配路徑或主機的URI變量。URI變量可用于該值,并將在運行時擴展。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_request_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/foo/{segment<span style="color:#7f0055"><strong>}</strong></span>
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddRequestHeader</span>=X-Request-Foo<span style="color:#7f0055"><strong>,</strong></span> Bar-{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

115.2 AddRequestParameter GatewayFilter工廠

AddRequestParameter?GatewayFilter工廠采用namevalue參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_request_parameter_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddRequestParameter</span>=foo<span style="color:#7f0055"><strong>,</strong></span> bar</span></span></span>

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

AddRequestParameter知道用于匹配路徑或主機的URI變量。URI變量可用于該值,并將在運行時擴展。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_request_parameter_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>: {segment}.myhost.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddRequestParameter</span>=foo<span style="color:#7f0055"><strong>,</strong></span> bar-{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

115.3 AddResponseHeader GatewayFilter工廠

AddResponseHeader?GatewayFilter工廠采用namevalue參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_response_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddResponseHeader</span>=X-Response-Foo<span style="color:#7f0055"><strong>,</strong></span> Bar</span></span></span>

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

AddResponseHeader知道用于匹配路徑或主機的URI變量。URI變量可用于該值,并將在運行時擴展。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: add_response_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>: {segment}.myhost.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - AddResponseHeader</span>=foo<span style="color:#7f0055"><strong>,</strong></span> bar-{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

115.4 DedupeResponseHeader GatewayFilter工廠

DedupeResponseHeader?GatewayFilter工廠采用name參數和可選的strategy參數。name可以包含標題名稱列表,以空格分隔。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: dedupe_response_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - DedupeResponseHeader</span>=Access-Control-Allow-Credentials Access-Control-Allow-Origin</span></span></span>

在網關CORS邏輯和下游邏輯都將它們添加的情況下,這將刪除Access-Control-Allow-CredentialsAccess-Control-Allow-Origin響應頭的重復值。

DedupeResponseHeader過濾器還接受可選的strategy參數。可接受的值為RETAIN_FIRST(默認值),RETAIN_LASTRETAIN_UNIQUE

115.5 Hystrix GatewayFilter工廠

Hystrix是Netflix的一個庫,它實現了斷路器模式。Hystrix?GatewayFilter允許您將斷路器引入網關路由,保護服務免受級聯故障的影響,并允許您在下游故障的情況下提供后備響應。

要在您的項目中啟用Hystrix?GatewayFilters,請添加對Spring Cloud Netflix中的?spring-cloud-starter-netflix-hystrix的依賴。

Hystrix?GatewayFilter工廠需要一個name參數,它是HystrixCommand的名稱。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: hystrix_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - Hystrix</span>=myCommandName</span></span></span>

這會將其余過濾器包裝在命令名稱為myCommandNameHystrixCommand中。

Hystrix過濾器還可以接受可選的fallbackUri參數。當前,僅支持forward:計劃的URI。如果調用了后備,則請求將被轉發到與URI相匹配的控制器。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: hystrix_route
<span style="color:#7f007f">        uri</span>: lb://backing-service:8088
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/consumingserviceendpoint
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: Hystrix
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            name</span>: fallbackcmd
<span style="color:#7f007f">            fallbackUri</span>: forward:/incaseoffailureusethis
<span style="color:#7f007f">        - RewritePath</span>=/consumingserviceendpoint<span style="color:#7f0055"><strong>,</strong></span> /backingserviceendpoint</span></span></span>

調用Hystrix后備廣告時,它將轉發到/incaseoffailureusethis?URI。請注意,此示例還通過目標URI上的lb前綴演示了(可選)Spring Cloud Netflix Ribbon負載均衡。

主要方案是將fallbackUri用于網關應用程序中的內部控制器或處理程序。但是,也可以將請求重新路由到外部應用程序中的控制器或處理程序,如下所示:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: ingredients
<span style="color:#7f007f">        uri</span>: lb://ingredients
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=//ingredients/**
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: Hystrix
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            name</span>: fetchIngredients
<span style="color:#7f007f">            fallbackUri</span>: forward:/fallback
<span style="color:#7f007f">      - id</span>: ingredients-fallback
<span style="color:#7f007f">        uri</span>: http://localhost:9994
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/fallback</span></span></span>

在此示例中,網關應用程序中沒有fallback端點或處理程序,但是,另一個應用程序中沒有fallback端點或處理程序,已在http://localhost:9994下注冊。

如果將請求轉發到后備,則Hystrix網關過濾器還會提供引起請求的Throwable。它作為ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR屬性添加到ServerWebExchange中,可以在網關應用程序中處理后備時使用。

對于外部控制器/處理程序方案,可以添加帶有異常詳細信息的標頭。您可以在FallbackHeaders GatewayFilter Factory部分中找到有關它的更多信息。

Hystrix設置(例如超時)可以使用全局默認值進行配置,也可以使用Hystrix Wiki中所述的應用程序屬性在逐條路由的基礎上進行配置。

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

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds</span>: 5000</span></span></span>

115.6 FallbackHeaders GatewayFilter工廠

FallbackHeaders工廠允許您在轉發到外部應用程序中的fallbackUri的請求的標頭中添加Hystrix執行異常詳細信息,例如以下情況:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: ingredients
<span style="color:#7f007f">        uri</span>: lb://ingredients
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=//ingredients/**
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: Hystrix
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            name</span>: fetchIngredients
<span style="color:#7f007f">            fallbackUri</span>: forward:/fallback
<span style="color:#7f007f">      - id</span>: ingredients-fallback
<span style="color:#7f007f">        uri</span>: http://localhost:9994
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/fallback
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: FallbackHeaders
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            executionExceptionTypeHeaderName</span>: Test-Header</span></span></span>

在此示例中,在運行HystrixCommand時發生執行異常之后,該請求將轉發到fallback端點或運行在localhost:9994上的應用程序中的處理程序。具有異常類型,消息和-if available-根本原因異常類型和消息的標頭將由FallbackHeaders過濾器添加到該請求。

通過設置下面列出的參數的值及其默認值,可以在配置中覆蓋標頭的名稱:

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

您可以在Hystrix GatewayFilter工廠部分中找到有關Hystrix與Gateway一起工作的更多信息。

115.7 MapRequestHeader GatewayFilter工廠

MapRequestHeader?GatewayFilter要素采用'fromHeader'和'toHeader'參數。它創建一個新的命名標頭(toHeader),并從傳入的HTTP請求中從現有的命名標頭(fromHeader)中提取值。如果輸入標頭不存在,則過濾器不起作用。如果新的命名標頭已經存在,則將使用新值擴充其值。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: map_request_header_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - MapRequestHeader</span>=Bar<span style="color:#7f0055"><strong>,</strong></span> X-Request-Foo</span></span></span>

這會將X-Request-Foo:<values>標頭添加到下游請求中,并帶有來自傳入的HTTP請求Bar標頭的更新值。

115.8 PrefixPath GatewayFilter工廠

PrefixPath?GatewayFilter工廠采用單個prefix參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: prefixpath_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - PrefixPath</span>=/mypath</span></span></span>

這會將/mypath作為所有匹配請求的路徑的前綴。因此,對/hello的請求將被發送到/mypath/hello

115.9 PreserveHostHeader GatewayFilter工廠

PreserveHostHeader?GatewayFilter工廠沒有參數。該過濾器設置請求屬性,路由過濾器將檢查該請求屬性以確定是否應發送原始主機頭,而不是由HTTP客戶端確定的主機頭。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: preserve_host_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:- PreserveHostHeader</span></span></span>

115.10 RequestRateLimiter GatewayFilter工廠

RequestRateLimiter?GatewayFilter工廠使用RateLimiter實現來確定是否允許繼續當前請求。如果不是,則返回狀態HTTP 429 - Too Many Requests(默認)。

該過濾器采用一個可選的keyResolver參數和特定于速率限制器的參數(請參見下文)。

keyResolver是實現KeyResolver接口的bean。在配置中,使用SpEL通過名稱引用bean。#{@myKeyResolver}是引用名稱為myKeyResolver的bean的SpEL表達式。

KeyResolver.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>interface</strong></span> KeyResolver {Mono<String> resolve(ServerWebExchange exchange);
}</span></span></span>

KeyResolver接口允許可插拔策略派生用于限制請求的密鑰。在未來的里程碑中,將有一些KeyResolver實現。

KeyResolver的默認實現是PrincipalNameKeyResolver,它從ServerWebExchange檢索Principal并調用Principal.getName()

默認情況下,如果KeyResolver未找到密鑰,則請求將被拒絕。可以使用spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key(對或錯)和spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code屬性來調整此行為。

[注意]

無法通過“快捷方式”符號配置RequestRateLimiter。以下示例無效

application.properties。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"># INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}</span></span></span>

115.10.1 Redis RateLimiter

redis實現基于Stripe所做的工作。它需要使用spring-boot-starter-data-redis-reactive?Spring Boot起動器。

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

redis-rate-limiter.replenishRate是您希望用戶每秒允許多少個請求,而沒有任何丟棄的請求。這是令牌桶被填充的速率。

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

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

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: requestratelimiter_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: RequestRateLimiter
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            redis-rate-limiter.replenishRate</span>: 10
<span style="color:#7f007f">            redis-rate-limiter.burstCapacity</span>: 20</span></span></span>

Config.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@Bean</span></em>
KeyResolver userKeyResolver() {<span style="color:#7f0055"><strong>return</strong></span> exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst(<span style="color:#2a00ff">"user"</span>));
}</span></span></span>

這定義了每個用戶10的請求速率限制。允許20個突發,但是下一秒只有10個請求可用。KeyResolver是一個簡單的參數,它獲取user請求參數(注意:不建議在生產中使用)。

速率限制器也可以定義為實現RateLimiter接口的bean。在配置中,使用SpEL通過名稱引用bean。#{@myRateLimiter}是一個SpEL表達式,引用名稱為myRateLimiter的bean。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: requestratelimiter_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: RequestRateLimiter
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            rate-limiter</span>: <span style="color:#2a00ff">"#{@myRateLimiter}"</span>
<span style="color:#7f007f">            key-resolver</span>: <span style="color:#2a00ff">"#{@userKeyResolver}"</span></span></span></span>

115.11重定向到GatewayFilter工廠

RedirectTo?GatewayFilter工廠采用一個status和一個url參數。狀態應該是300系列重定向http代碼,例如301。URL應該是有效的URL。這將是Location標頭的值。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: prefixpath_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RedirectTo</span>=302<span style="color:#7f0055"><strong>,</strong></span> https://acme.org</span></span></span>

這將發送帶有Location:https://acme.org標頭的狀態302以執行重定向。

115.12 RemoveRequestHeader GatewayFilter工廠

RemoveRequestHeader?GatewayFilter工廠采用一個name參數。它是要刪除的標題的名稱。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: removerequestheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RemoveRequestHeader</span>=X-Request-Foo</span></span></span>

這將刪除X-Request-Foo標頭,然后將其發送到下游。

115.13 RemoveResponseHeader GatewayFilter工廠

RemoveResponseHeader?GatewayFilter工廠采用一個name參數。它是要刪除的標題的名稱。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: removeresponseheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RemoveResponseHeader</span>=X-Response-Foo</span></span></span>

這會將X-Response-Foo標頭從響應中刪除,然后將其返回到網關客戶端。

要刪除任何類型的敏感標頭,應為可能需要的任何路由配置此過濾器。此外,您可以使用spring.cloud.gateway.default-filters一次配置此過濾器,并將其應用于所有路由。

115.14 RewritePath GatewayFilter工廠

RewritePath?GatewayFilter工廠采用路徑regexp參數和replacement參數。這使用Java正則表達式提供了一種靈活的方式來重寫請求路徑。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: rewritepath_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/foo/**
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RewritePath</span>=/foo(?<segment>/?.*)<span style="color:#7f0055"><strong>,</strong></span> $\{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

對于/foo/bar的請求路徑,這將在發出下游請求之前將路徑設置為/bar。請注意,由于YAML規范,$\$所取代。

115.15 RewriteLocationResponseHeader GatewayFilter工廠

RewriteLocationResponseHeader?GatewayFilter工廠通常會修改Location響應標頭的值,以擺脫后端特定的詳細信息。它需要stripVersionModelocationHeaderNamehostValueprotocolsRegex參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: rewritelocationresponseheader_route
<span style="color:#7f007f">        uri</span>: http://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RewriteLocationResponseHeader</span>=AS_IN_REQUEST<span style="color:#7f0055"><strong>,</strong></span> Location<span style="color:#7f0055"><strong>,</strong></span> <span style="color:#7f0055"><strong>,</strong></span></span></span></span>

例如,對于請求POST?https://api.example.com/some/object/nameLocation響應標頭值https://object-service.prod.example.net/v2/some/object/id將被重寫為https://api.example.com/some/object/id

參數stripVersionMode具有以下可能的值:NEVER_STRIPAS_IN_REQUEST(默認),ALWAYS_STRIP

  • NEVER_STRIP-即使原始請求路徑不包含版本,也不會剝離版本
  • AS_IN_REQUEST-僅當原始請求路徑不包含版本時,版本才會被剝離
  • ALWAYS_STRIP-即使原始請求路徑包含版本,也會剝離版本

參數hostValue(如果提供)將用于替換響應Location標頭中的host:port部分。如果未提供,將使用Host請求標頭的值。

參數protocolsRegex必須是有效的正則表達式String,協議名稱將與之匹配。如果不匹配,過濾器將不執行任何操作。默認值為http|https|ftp|ftps

115.16 RewriteResponseHeader GatewayFilter工廠

RewriteResponseHeader?GatewayFilter工廠采用nameregexpreplacement參數。它使用Java正則表達式以靈活的方式重寫響應標頭值。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: rewriteresponseheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - RewriteResponseHeader</span>=X-Response-Foo<span style="color:#7f0055"><strong>,</strong></span> <span style="color:#7f0055"><strong>,</strong></span> password=[^&]+<span style="color:#7f0055"><strong>,</strong></span> password=***</span></span></span>

對于標頭值為/42?user=ford&password=omg!what&flag=true,在發出下游請求后它將被設置為/42?user=ford&password=***&flag=true。由于YAML規范,請使用$\來表示$

115.17 SaveSession GatewayFilter工廠

向下游轉發呼叫之前,SaveSession GatewayFilter工廠強制執行WebSession::save操作。這在將Spring Session之類的內容用于惰性數據存儲并且需要確保在進行轉接呼叫之前已保存會話狀態時特別有用。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: save_session
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/foo/**
<span style="color:#7f007f">        filters</span>:- SaveSession</span></span></span>

如果您將Spring Security與Spring Session?集成在一起,并且想要確保安全性詳細信息已轉發到遠程進程,則至關重要。

115.18 SecureHeaders GatewayFilter工廠

SecureHeaders?GatewayFilter Factory根據此博客文章的建議向響應中添加了許多標頭。

添加了以下標頭(以及默認值):

  • 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名稱空間中設置適當的屬性:

Property進行更改:

  • 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.disable

[注意]

需要使用小寫和安全標頭的全名。

可以使用以下值:

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

例:?spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security

115.19 SetPath GatewayFilter工廠

SetPath?GatewayFilter工廠采用路徑template參數。通過允許路徑的模板段,它提供了一種操作請求路徑的簡單方法。這將使用Spring Framework中的uri模板。允許多個匹配段。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setpath_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/foo/{segment<span style="color:#7f0055"><strong>}</strong></span>
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetPath</span>=/{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

對于/foo/bar的請求路徑,這將在發出下游請求之前將路徑設置為/bar

115.20 SetRequestHeader GatewayFilter工廠

SetRequestHeader?GatewayFilter工廠采用namevalue參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setrequestheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetRequestHeader</span>=X-Request-Foo<span style="color:#7f0055"><strong>,</strong></span> Bar</span></span></span>

該GatewayFilter用給定的名稱替換所有標頭,而不是添加。因此,如果下游服務器響應X-Request-Foo:1234,則將其替換為X-Request-Foo:Bar,下游服務將收到此信息。

SetRequestHeader知道用于匹配路徑或主機的URI變量。URI變量可用于該值,并將在運行時擴展。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setrequestheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>: {segment}.myhost.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetRequestHeader</span>=foo<span style="color:#7f0055"><strong>,</strong></span> bar-{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

115.21 SetResponseHeader GatewayFilter工廠

SetResponseHeader?GatewayFilter工廠采用namevalue參數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setresponseheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetResponseHeader</span>=X-Response-Foo<span style="color:#7f0055"><strong>,</strong></span> Bar</span></span></span>

該GatewayFilter用給定的名稱替換所有標頭,而不是添加。因此,如果下游服務器以X-Response-Foo:1234響應,則將其替換為X-Response-Foo:Bar,這是網關客戶端將收到的內容。

SetResponseHeader知道用于匹配路徑或主機的URI變量。URI變量可用于該值,并將在運行時擴展。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setresponseheader_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>: {segment}.myhost.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetResponseHeader</span>=foo<span style="color:#7f0055"><strong>,</strong></span> bar-{segment<span style="color:#7f0055"><strong>}</strong></span></span></span></span>

115.22 SetStatus GatewayFilter工廠

SetStatus?GatewayFilter工廠采用單個status參數。它必須是有效的Spring?HttpStatus。它可以是整數值404,也可以是枚舉NOT_FOUND的字符串表示形式。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setstatusstring_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetStatus</span>=BAD_REQUEST
<span style="color:#7f007f">      - id</span>: setstatusint_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetStatus</span>=401</span></span></span>

無論哪種情況,響應的HTTP狀態都將設置為401。

115.23 StripPrefix GatewayFilter工廠

StripPrefix GatewayFilter工廠采用一個參數partsparts參數指示在向下游發送請求之前,要從請求中剝離的路徑中的零件數。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: nameRoot
<span style="color:#7f007f">        uri</span>: http://nameservice
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/name/**
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - StripPrefix</span>=2</span></span></span>

通過網關發送到/name/bar/foo的請求時,對nameservice的請求將類似于http://nameservice/foo

115.24重試GatewayFilter工廠

Retry?GatewayFilter Factory支持以下參數集:

  • retries:應嘗試重試的次數
  • statuses:應重試的HTTP狀態代碼,用org.springframework.http.HttpStatus表示
  • methods:應重試的HTTP方法,使用org.springframework.http.HttpMethod表示
  • series:要重試的一系列狀態代碼,使用org.springframework.http.HttpStatus.Series表示
  • exceptions:應重試引發的異常列表
  • backoff:為重試配置了指數補償。重試在退避間隔firstBackoff * (factor ^ n)之后執行,其中n是迭代。如果配置了maxBackoff,則應用的最大退避將被限制為maxBackoff。如果basedOnPreviousValue為true,將使用prevBackoff * factor計算退避。

如果啟用了Retry過濾器,則會配置以下默認值:

  • retries-3次
  • series?— 5XX系列
  • methods?— GET方法
  • exceptions-IOExceptionTimeoutException
  • backoff-已禁用

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: retry_test
<span style="color:#7f007f">        uri</span>: http://localhost:8080/flakey
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Host</span>=*.retry.com
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: Retry
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            retries</span>: 3
<span style="color:#7f007f">            statuses</span>: BAD_GATEWAY
<span style="color:#7f007f">            methods</span>: GET,POST
<span style="color:#7f007f">            backoff</span>:
<span style="color:#7f007f">              firstBackoff</span>: 10ms
<span style="color:#7f007f">              maxBackoff</span>: 50ms
<span style="color:#7f007f">              factor</span>: 2
<span style="color:#7f007f">              basedOnPreviousValue</span>: <span style="color:#7f0055"><strong>false</strong></span></span></span></span>

[注意]

當使用帶有forward:前綴URL的重試過濾器時,應仔細編寫目標端點,以便在發生錯誤的情況下不會執行任何可能導致響應發送到客戶端并提交的操作。例如,如果目標端點是帶注釋的控制器,則目標控制器方法不應返回帶有錯誤狀態代碼的ResponseEntity。相反,它應該拋出一個Exception,或者例如通過一個Mono.error(ex)返回值來發出錯誤信號,可以將重試過濾器配置為通過重試來處理。

[警告]

當將重試過濾器與任何具有主體的HTTP方法一起使用時,主體將被緩存,并且網關將受到內存的限制。正文被緩存在ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR定義的請求屬性中。對象的類型是org.springframework.core.io.buffer.DataBuffer

115.25 RequestSize GatewayFilter工廠

當請求大小大于允許的限制時,RequestSize?GatewayFilter工廠可以限制請求到達下游服務。過濾器采用maxSize參數,該參數是請求的允許大小限制。maxSize is a `DataSize類型,因此值可以定義為數字,后跟可選的DataUnit后綴,例如'KB'或'MB'。字節的默認值為“ B”。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: request_size_route
<span style="color:#7f007f">      uri</span>: http://localhost:8080/upload
<span style="color:#7f007f">      predicates</span>:
<span style="color:#7f007f">      - Path</span>=/upload
<span style="color:#7f007f">      filters</span>:
<span style="color:#7f007f">      - name</span>: RequestSize
<span style="color:#7f007f">        args</span>:
<span style="color:#7f007f">          maxSize</span>: 5000000</span></span></span>

當請求因大小而被拒絕時,RequestSize GatewayFilter Factory將響應狀態設置為413 Payload Too Large,并帶有一個附加報頭errorMessage。以下是此類errorMessage的示例。

errorMessage?:?Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB

[注意]

如果未在路由定義中作為過濾器參數提供,則默認請求大小將設置為5 MB。

115.26修改請求正文GatewayFilter工廠

該過濾器被認為是BETA,API將來可能會更改

ModifyRequestBody過濾器可用于在網關向下游發送請求主體之前修改請求主體。

[注意]

只能使用Java DSL配置此過濾器

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> RouteLocator routes(RouteLocatorBuilder builder) {<span style="color:#7f0055"><strong>return</strong></span> builder.routes().route(<span style="color:#2a00ff">"rewrite_request_obj"</span>, r -> r.host(<span style="color:#2a00ff">"*.rewriterequestobj.org"</span>).filters(f -> f.prefixPath(<span style="color:#2a00ff">"/httpbin"</span>).modifyRequestBody(String.<span style="color:#7f0055"><strong>class</strong></span>, Hello.<span style="color:#7f0055"><strong>class</strong></span>, MediaType.APPLICATION_JSON_VALUE,(exchange, s) -> <span style="color:#7f0055"><strong>return</strong></span> Mono.just(<span style="color:#7f0055"><strong>new</strong></span> Hello(s.toUpperCase())))).uri(uri)).build();
}<span style="color:#7f0055"><strong>static</strong></span> <span style="color:#7f0055"><strong>class</strong></span> Hello {String message;<span style="color:#7f0055"><strong>public</strong></span> Hello() { }<span style="color:#7f0055"><strong>public</strong></span> Hello(String message) {<span style="color:#7f0055"><strong>this</strong></span>.message = message;}<span style="color:#7f0055"><strong>public</strong></span> String getMessage() {<span style="color:#7f0055"><strong>return</strong></span> message;}<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>void</strong></span> setMessage(String message) {<span style="color:#7f0055"><strong>this</strong></span>.message = message;}
}</span></span></span>

115.27修改響應主體GatewayFilter工廠

該過濾器被認為是BETA,API將來可能會更改

ModifyResponseBody過濾器可用于在將響應正文發送回客戶端之前對其進行修改。

[注意]

只能使用Java DSL配置此過濾器

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> RouteLocator routes(RouteLocatorBuilder builder) {<span style="color:#7f0055"><strong>return</strong></span> builder.routes().route(<span style="color:#2a00ff">"rewrite_response_upper"</span>, r -> r.host(<span style="color:#2a00ff">"*.rewriteresponseupper.org"</span>).filters(f -> f.prefixPath(<span style="color:#2a00ff">"/httpbin"</span>).modifyResponseBody(String.<span style="color:#7f0055"><strong>class</strong></span>, String.<span style="color:#7f0055"><strong>class</strong></span>,(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri).build();
}</span></span></span>

115.28默認過濾器

如果您要添加過濾器并將其應用于所有路由,則可以使用spring.cloud.gateway.default-filters。該屬性采用過濾器列表

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      default-filters</span>:
<span style="color:#7f007f">      - AddResponseHeader</span>=X-Response-Default-Foo<span style="color:#7f0055"><strong>,</strong></span> Default-Bar
<span style="color:#7f007f">      - PrefixPath</span>=/httpbin</span></span></span>

116.全局過濾器

GlobalFilter接口具有與GatewayFilter相同的簽名。這些是特殊過濾器,有條件地應用于所有路由。(此接口和用法可能會在將來的里程碑中更改)。

116.1組合的全局過濾器和GatewayFilter排序

當有請求進入(并與路由匹配)時,過濾Web處理程序會將GlobalFilter的所有實例和GatewayFilter的所有特定于路由的實例添加到過濾器鏈中。該組合的過濾器鏈通過org.springframework.core.Ordered接口排序,可以通過實現getOrder()方法進行設置。

由于Spring Cloud網關區分執行過濾器邏輯的“前”階段和“后”階段(請參閱:工作原理),因此,具有最高優先級的過濾器將在“前”階段中處于第一個階段,在“階段”中處于最后一個階段。 “后期”階段。

ExampleConfiguration.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> GlobalFilter customFilter() {<span style="color:#7f0055"><strong>return</strong></span> <span style="color:#7f0055"><strong>new</strong></span> CustomGlobalFilter();
}<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> CustomGlobalFilter <span style="color:#7f0055"><strong>implements</strong></span> GlobalFilter, Ordered {<em><span style="color:gray">@Override</span></em><span style="color:#7f0055"><strong>public</strong></span> Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(<span style="color:#2a00ff">"custom global filter"</span>);<span style="color:#7f0055"><strong>return</strong></span> chain.filter(exchange);}<em><span style="color:gray">@Override</span></em><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>int</strong></span> getOrder() {<span style="color:#7f0055"><strong>return</strong></span> -1;}
}</span></span></span>

116.2轉發路由過濾器

ForwardRoutingFilter在交換屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中尋找URI。如果該網址具有forward方案(即forward:///localendpoint),它將使用Spring?DispatcherHandler處理請求。請求URL的路徑部分將被轉發URL中的路徑覆蓋。未經修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。

116.3 LoadBalancerClient篩選器

LoadBalancerClientFilter在交換屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中尋找URI。如果該網址具有lb方案(即lb://myservice),它將使用Spring Cloud?LoadBalancerClient將名稱(上例中為myservice)解析為實際的主機和端口并替換相同屬性中的URI。未經修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。過濾器還將查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR屬性,以查看其是否等于lb,然后應用相同的規則。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: myRoute
<span style="color:#7f007f">        uri</span>: lb://service
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/service/**</span></span></span>

[注意]

默認情況下,當在LoadBalancer中找不到服務實例時,將返回503。您可以通過設置spring.cloud.gateway.loadbalancer.use404=true來配置網關以返回404

[注意]

LoadBalancer返回的ServiceInstanceisSecure值將覆蓋對網關的請求中指定的方案。例如,如果請求通過HTTPS進入網關,但ServiceInstance表示它不安全,則下游請求將通過HTTP發出。相反的情況也可以適用。但是,如果在網關配置中為路由指定了GATEWAY_SCHEME_PREFIX_ATTR,則前綴將被刪除,并且來自路由URL的結果方案將覆蓋ServiceInstance配置。

[警告]

LoadBalancerClientFilter在引擎蓋下使用阻擋物Ribbon?LoadBalancerClient。我們建議您改用ReactiveLoadBalancerClientFilter。您可以通過向項目添加org.springframework.cloud:spring-cloud-loadbalancer依賴項并將spring.cloud.loadbalancer.ribbon.enabled的值設置為false來切換為使用它。

116.4 ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter在交換屬性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中尋找URI。如果該網址具有lb方案(即lb://myservice),它將使用Spring Cloud?ReactorLoadBalancer將名稱(上例中為myservice)解析為實際的主機和端口并替換相同屬性中的URI。未經修改的原始URL會附加到ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR屬性中的列表中。過濾器還將查看ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR屬性,以查看其是否等于lb,然后應用相同的規則。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: myRoute
<span style="color:#7f007f">        uri</span>: lb://service
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/service/**</span></span></span>

[注意]

默認情況下,當ReactorLoadBalancer無法找到服務實例時,將返回503。您可以通過設置spring.cloud.gateway.loadbalancer.use404=true將網關配置為返回404

[注意]

ReactiveLoadBalancerClientFilter返回的ServiceInstanceisSecure值將覆蓋對網關的請求中指定的方案。例如,如果請求通過HTTPS進入網關,但ServiceInstance表示它不安全,則下游請求將通過HTTP發出。相反的情況也可以適用。但是,如果在網關配置中為路由指定了GATEWAY_SCHEME_PREFIX_ATTR,則前綴將被刪除,并且從路由URL生成的方案將覆蓋ServiceInstance配置。

116.5網絡路由過濾器

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中的URL具有httphttps方案,則將運行Netty路由篩選器。它使用Netty?HttpClient發出下游代理請求。響應將放在ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交換屬性中,以供以后的過濾器使用。(有一個實驗性WebClientHttpRoutingFilter,它執行相同的功能,但不需要凈值)

116.6 Netty寫響應過濾器

如果ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR交換屬性中有凈值HttpClientResponse,則NettyWriteResponseFilter將運行。它在所有其他篩選器完成后運行,并將代理響應寫回到網關客戶端響應。(有一個實驗性WebClientWriteResponseFilter,它執行相同的功能,但不需要凈值)

116.7 RouteToRequestUrl過濾器

如果ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR交換屬性中存在Route對象,則RouteToRequestUrlFilter將運行。它基于請求URI創建一個新URI,但使用Route對象的URI屬性進行了更新。新的URI放置在ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中。

如果URI具有方案前綴(例如lb:ws://serviceid),則將從URI中剝離lb方案,并將其放在ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR中,以供以后在過濾器鏈中使用。

116.8 Websocket路由過濾器

如果位于ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR交換屬性中的URL具有wswss方案,則Websocket路由篩選器將運行。它使用Spring Web套接字基礎結構向下游轉發Websocket請求。

通過在URI前面加上lb,例如lb:ws://serviceid,可以實現Websocket的負載均衡。

[注意]

如果您將SockJS用作常規http的后??備,則應配置常規HTTP路由以及Websocket路由。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:<span style="color:#3f5f5f"><em># SockJS route</em></span>
<span style="color:#7f007f">      - id</span>: websocket_sockjs_route
<span style="color:#7f007f">        uri</span>: http://localhost:3001
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/websocket/info/**<span style="color:#3f5f5f"><em># Normal Websocket route</em></span>
<span style="color:#7f007f">      - id</span>: websocket_route
<span style="color:#7f007f">        uri</span>: ws://localhost:3001
<span style="color:#7f007f">        predicates</span>:
<span style="color:#7f007f">        - Path</span>=/websocket/**</span></span></span>

116.9網關指標過濾器

要啟用網關度量標準,請添加spring-boot-starter-actuator作為項目依賴項。然后,默認情況下,只要屬性spring.cloud.gateway.metrics.enabled未設置為false,網關度量過濾器就會運行。該過濾器添加了一個帶有以下標記的名為“ gateway.requests”的計時器指標:

  • routeId:路線ID
  • routeUri:API將被路由到的URI
  • outcome:根據HttpStatus.Series分類的結果
  • status:返回給客戶端的請求的Http狀態
  • httpStatusCode:返回給客戶端的請求的Http狀態
  • httpMethod:用于請求的Http方法

然后可以從/actuator/metrics/gateway.requests?抓取?這些指標,并且可以輕松地將其與Prometheus集成以創建Grafana?儀表板。

[注意]

要啟用Prometheus端點,請添加micrometer-registry-prometheus作為項目依賴項。

116.10將交換標記為已路由

網關路由ServerWebExchange后,它將通過在交換屬性中添加gatewayAlreadyRouted將該交換標記為“已路由”。將請求標記為已路由后,其他路由篩選器將不會再次路由請求,實質上會跳過該篩選器。您可以使用多種便捷方法將交換標記為已路由,或者檢查交換是否已路由。

  • ServerWebExchangeUtils.isAlreadyRouted接受ServerWebExchange對象,并檢查其是否已“路由”
  • ServerWebExchangeUtils.setAlreadyRouted接受ServerWebExchange對象,并將其標記為“已路由”

117. HttpHeadersFilters

HttpHeadersFilters在向下游發送請求之前(例如,在NettyRoutingFilter中)已應用于請求。

117.1轉發的標題過濾器

Forwarded標頭過濾器創建一個Forwarded標頭,以發送到下游服務。它將當前請求的Host標頭,方案和端口添加到任何現有的Forwarded標頭中。

117.2 RemoveHopByHop標頭過濾器

RemoveHopByHop標頭過濾器從轉發的請求中刪除標頭。被刪除的頭的默認列表來自IETF。

默認刪除的標題為:

  • 連接
  • 活著
  • 代理驗證
  • 代理授權
  • TE
  • 預告片
  • 傳輸編碼
  • 升級

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

117.3 XForwarded標頭過濾器

XForwarded標頭過濾器創建各種X-Forwarded-*標頭,以發送到下游服務。它使用Host頭,當前請求的方案,端口和路徑來創建各種頭。

可以通過以下布爾屬性(默認為true)控制單個標題的創建:

  • spring.cloud.gateway.x-forwarded.for.enabled
  • spring.cloud.gateway.x-forwarded.host.enabled
  • spring.cloud.gateway.x-forwarded.port.enabled
  • spring.cloud.gateway.x-forwarded.proto.enabled
  • spring.cloud.gateway.x-forwarded.prefix.enabled

可以通過以下布爾屬性(默認為true)控制追加多個標頭:

  • spring.cloud.gateway.x-forwarded.for.append
  • spring.cloud.gateway.x-forwarded.host.append
  • spring.cloud.gateway.x-forwarded.port.append
  • spring.cloud.gateway.x-forwarded.proto.append
  • spring.cloud.gateway.x-forwarded.prefix.append

118. TLS / SSL

網關可以通過遵循常規的Spring服務器配置來偵聽https上的請求。例:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">server</span>:
<span style="color:#7f007f">  ssl</span>:
<span style="color:#7f007f">    enabled</span>: <span style="color:#7f0055"><strong>true</strong></span>
<span style="color:#7f007f">    key-alias</span>: scg
<span style="color:#7f007f">    key-store-password</span>: scg1234
<span style="color:#7f007f">    key-store</span>: classpath:scg-keystore.p12
<span style="color:#7f007f">    key-store-type</span>: PKCS12</span></span></span>

網關路由可以同時路由到http和https后端。如果路由到https后端,則可以使用以下配置將網關配置為信任所有下游證書:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      httpclient</span>:
<span style="color:#7f007f">        ssl</span>:
<span style="color:#7f007f">          useInsecureTrustManager</span>: <span style="color:#7f0055"><strong>true</strong></span></span></span></span>

使用不安全的信任管理器不適用于生產。對于生產部署,可以為網關配置一組可以通過以下配置信任的已知證書:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      httpclient</span>:
<span style="color:#7f007f">        ssl</span>:
<span style="color:#7f007f">          trustedX509Certificates</span>:- cert1.pem- cert2.pem</span></span></span>

如果Spring Cloud網關未配置受信任的證書,則使用默認的信任存儲(可以使用系統屬性javax.net.ssl.trustStore覆蓋)。

118.1 TLS握手

網關維護一個客戶端池,該客戶端池用于路由到后端。通過https進行通信時,客戶端會啟動TLS握手。許多超時與此握手相關聯。可以配置以下超時(顯示默認值):

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      httpclient</span>:
<span style="color:#7f007f">        ssl</span>:
<span style="color:#7f007f">          handshake-timeout-millis</span>: 10000
<span style="color:#7f007f">          close-notify-flush-timeout-millis</span>: 3000
<span style="color:#7f007f">          close-notify-read-timeout-millis</span>: 0</span></span></span>

119.配置

Spring Cloud網關的配置由RouteDefinitionLocator的集合驅動。

RouteDefinitionLocator.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>interface</strong></span> RouteDefinitionLocator {Flux<RouteDefinition> getRouteDefinitions();
}</span></span></span>

默認情況下,PropertiesRouteDefinitionLocator使用Spring Boot的@ConfigurationProperties機制加載屬性。

上面的所有配置示例都使用一種快捷方式符號,該快捷方式符號使用位置參數而不是命名參數。以下兩個示例是等效的:

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      routes</span>:
<span style="color:#7f007f">      - id</span>: setstatus_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - name</span>: SetStatus
<span style="color:#7f007f">          args</span>:
<span style="color:#7f007f">            status</span>: 401
<span style="color:#7f007f">      - id</span>: setstatusshortcut_route
<span style="color:#7f007f">        uri</span>: https://example.org
<span style="color:#7f007f">        filters</span>:
<span style="color:#7f007f">        - SetStatus</span>=401</span></span></span>

對于網關的某些用法,屬性將是足夠的,但某些生產用例將受益于從外部源(例如數據庫)加載配置。未來的里程碑版本將基于Spring Data Repositories實現RouteDefinitionLocator實現,例如:Redis,MongoDB和Cassandra。

119.1 Fluent Java Routes API

為了在Java中進行簡單的配置,在RouteLocatorBuilder?bean中定義了一個流暢的API。

GatewaySampleApplication.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#3f5f5f"><em>// static imports from GatewayFilters and RoutePredicates</em></span>
<em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {<span style="color:#7f0055"><strong>return</strong></span> builder.routes().route(r -> r.host(<span style="color:#2a00ff">"**.abc.org"</span>).and().path(<span style="color:#2a00ff">"/image/png"</span>).filters(f ->f.addResponseHeader(<span style="color:#2a00ff">"X-TestHeader"</span>, <span style="color:#2a00ff">"foobar"</span>)).uri(<span style="color:#2a00ff">"http://httpbin.org:80"</span>)).route(r -> r.path(<span style="color:#2a00ff">"/image/webp"</span>).filters(f ->f.addResponseHeader(<span style="color:#2a00ff">"X-AnotherHeader"</span>, <span style="color:#2a00ff">"baz"</span>)).uri(<span style="color:#2a00ff">"http://httpbin.org:80"</span>)).route(r -> r.order(-1).host(<span style="color:#2a00ff">"**.throttle.org"</span>).and().path(<span style="color:#2a00ff">"/get"</span>).filters(f -> f.filter(throttle.apply(1,1,10,TimeUnit.SECONDS))).uri(<span style="color:#2a00ff">"http://httpbin.org:80"</span>)).build();
}</span></span></span>

此樣式還允許更多自定義謂詞斷言。RouteDefinitionLocator?beans定義的謂詞使用邏輯and進行組合。通過使用流暢的Java API,您可以在Predicate類上使用and()or()negate()運算符。

119.2 DiscoveryClient路由定義定位器

可以將網關配置為基于在DiscoveryClient兼容服務注冊表中注冊的服務來創建路由。

要啟用此功能,請設置spring.cloud.gateway.discovery.locator.enabled=true并確保在類路徑上啟用了DiscoveryClient實現(例如Netflix Eureka,Consul或Zookeeper)。

119.2.1為DiscoveryClient路由配置謂詞和過濾器

默認情況下,網關為通過DiscoveryClient創建的路由定義單個謂詞和過濾器。

默認謂詞是使用模式/serviceId/**定義的路徑謂詞,其中serviceIdDiscoveryClient中服務的ID。

缺省過濾器是帶有正則表達式/serviceId/(?<remaining>.*)和替換文本/${remaining}的重寫路徑過濾器。這只是在將請求發送到下游之前從路徑中剝離服務ID。

如果要自定義DiscoveryClient路由使用的謂詞和/或過濾器,可以通過設置spring.cloud.gateway.discovery.locator.predicates[x]spring.cloud.gateway.discovery.locator.filters[y]來實現。這樣做時,如果要保留該功能,則需要確保在上面包含默認謂詞和過濾器。以下是此示例的示例。

application.properties。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: Hystrix
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"</span></span></span>

120. Reactor Netty訪問日志

要啟用Reactor Netty訪問日志,請設置-Dreactor.netty.http.server.accessLogEnabled=true。(它必須是Java系統Property,而不是Spring Boot屬性)。

日志系統可以配置為具有單獨的訪問日志文件。以下是示例登錄配置:

logback.xml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">    <span style="color:#3f7f7f"><appender</span> <span style="color:#7f007f">name</span>=<span style="color:#2a00ff">"accessLog"</span> <span style="color:#7f007f">class</span>=<span style="color:#2a00ff">"ch.qos.logback.core.FileAppender"</span><span style="color:#3f7f7f">></span><span style="color:#3f7f7f"><file></span>access_log.log<span style="color:#3f7f7f"></file></span><span style="color:#3f7f7f"><encoder></span><span style="color:#3f7f7f"><pattern></span>%msg%n<span style="color:#3f7f7f"></pattern></span><span style="color:#3f7f7f"></encoder></span><span style="color:#3f7f7f"></appender></span><span style="color:#3f7f7f"><appender</span> <span style="color:#7f007f">name</span>=<span style="color:#2a00ff">"async"</span> <span style="color:#7f007f">class</span>=<span style="color:#2a00ff">"ch.qos.logback.classic.AsyncAppender"</span><span style="color:#3f7f7f">></span><span style="color:#3f7f7f"><appender-ref</span> <span style="color:#7f007f">ref</span>=<span style="color:#2a00ff">"accessLog"</span><span style="color:#3f7f7f"> /></span><span style="color:#3f7f7f"></appender></span><span style="color:#3f7f7f"><logger</span> <span style="color:#7f007f">name</span>=<span style="color:#2a00ff">"reactor.netty.http.server.AccessLog"</span> <span style="color:#7f007f">level</span>=<span style="color:#2a00ff">"INFO"</span> <span style="color:#7f007f">additivity</span>=<span style="color:#2a00ff">"false"</span><span style="color:#3f7f7f">></span><span style="color:#3f7f7f"><appender-ref</span> <span style="color:#7f007f">ref</span>=<span style="color:#2a00ff">"async"</span><span style="color:#3f7f7f">/></span><span style="color:#3f7f7f"></logger></span></span></span></span>

121. CORS配置

可以將網關配置為控制CORS行為。“全局” CORS配置是URL模式到Spring Framework?CorsConfiguration的映射。

application.yml。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring</span>:
<span style="color:#7f007f">  cloud</span>:
<span style="color:#7f007f">    gateway</span>:
<span style="color:#7f007f">      globalcors</span>:
<span style="color:#7f007f">        corsConfigurations</span>:
<span style="color:#7f007f">          '[/**]'</span>:
<span style="color:#7f007f">            allowedOrigins</span>: <span style="color:#2a00ff">"https://docs.spring.io"</span>
<span style="color:#7f007f">            allowedMethods</span>:- GET</span></span></span>

在上面的示例中,對于所有GET請求的路徑,來自docs.spring.io的請求都將允許CORS請求。

要為未被某些網關路由謂詞處理的請求提供相同的CORS配置,請將屬性spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping設置為true。當嘗試支持CORS預檢請求并且您的路由謂詞未評估為true時,這很有用,因為http方法為options

122.執行器API

/gateway執行器端點允許監視Spring Cloud Gateway應用程序并與之交互。為了可遠程訪問,必須在應用程序屬性中通過HTTP或JMX?啟用和公開端點。

application.properties。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">management.endpoint.gateway.enabled</span>=true <span style="color:#3f5f5f"><em># default value</em></span>
<span style="color:#7f007f">management.endpoints.web.exposure.include</span>=gateway</span></span></span>

122.1詳細執行器格式

一種新的,更詳細的格式已添加到網關。這為每個路由增加了更多細節,從而允許查看與每個路由關聯的謂詞和過濾器以及任何可用的配置。

/actuator/gateway/routes

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>[</strong></span><span style="color:#7f0055"><strong>{</strong></span><span style="color:#2a00ff">"predicate"</span>: <span style="color:#2a00ff">"(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)"</span><span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"route_id"</span>: <span style="color:#2a00ff">"add_request_header_test"</span><span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"filters"</span>: <span style="color:#7f0055"><strong>[</strong></span><span style="color:#2a00ff">"[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]"</span><span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]"</span><span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"[[PrefixPath prefix = '/httpbin'], order = 2]"</span>]<span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"uri"</span>: <span style="color:#2a00ff">"lb://testservice"</span><span style="color:#7f0055"><strong>,</strong></span><span style="color:#2a00ff">"order"</span>: 0<span style="color:#7f0055"><strong>}</strong></span>
<span style="color:#7f0055"><strong>]</strong></span></span></span></span>

要啟用此功能,請設置以下屬性:

application.properties。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f007f">spring.cloud.gateway.actuator.verbose.enabled</span>=true</span></span></span>

在將來的版本中,該默認值為true。

122.2檢索路由過濾器

122.2.1全局過濾器

要檢索應用于所有路由的全局過濾器,請向/actuator/gateway/globalfilters發出GET請求。產生的響應類似于以下內容:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">{"org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5": 10100,"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,"org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
}</span></span></span>

該響應包含適當的全局過濾器的詳細信息。為每個全局過濾器提供過濾器對象的字符串表示形式(例如org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@77856cc5)和過濾器鏈中的相應順序。

122.2.2路由過濾器

要檢索應用于路由的GatewayFilter工廠,請向/actuator/gateway/routefilters發出GET請求。產生的響應類似于以下內容:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">{"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}</span></span></span>

該響應包含應用于任何特定路由的GatewayFilter工廠的詳細信息。為每個工廠提供相應對象的字符串表示形式(例如[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object])。請注意,null值是由于端點控制器的實現不完整而導致的,因為它試圖設置對象在過濾器鏈中的順序,該順序不適用于GatewayFilter工廠對象。

122.3刷新路由緩存

要清除路由緩存,請向/actuator/gateway/refresh發出POST請求。該請求返回200,但沒有響應主體。

122.4檢索網關中定義的路由

要檢索網關中定義的路由,請向/actuator/gateway/routes發出GET請求。產生的響應類似于以下內容:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">[{"route_id": "first_route","route_object": {"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d","filters": ["OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"]},"order": 0
},
{"route_id": "second_route","route_object": {"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298","filters": []},"order": 0
}]</span></span></span>

該響應包含網關中定義的所有路由的詳細信息。下表描述了響應的每個元素(即路線)的結構。

路徑類型描述

route_id

String

The route id.

route_object.predicate

Object

The route predicate.

route_object.filters

Array

The?GatewayFilter factories?applied to the route.

order

Number

The route order.

122.5檢索有關特定路線的信息

要檢索有關一條路線的信息,請向/actuator/gateway/routes/{id}發送一個GET請求(例如/actuator/gateway/routes/first_route)。產生的響應類似于以下內容:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8">{"id": "first_route","predicates": [{"name": "Path","args": {"_genkey_0":"/first"}}],"filters": [],"uri": "https://www.uri-destination.org","order": 0
}]</span></span></span>

下表描述了響應的結構。

路徑類型描述

id

String

The route id.

predicates

Array

The collection of route predicates. Each item defines the name and the arguments of a given predicate.

filters

Array

The collection of filters applied to the route.

uri

String

The destination URI of the route.

order

Number

The route order.

122.6創建和刪除特定路線

要創建路由,請使用指定路由字段的JSON正文向/gateway/routes/{id_route_to_create}發出POST請求(請參見上一小節)。

要刪除路由,請向/gateway/routes/{id_route_to_delete}發出DELETE請求。

122.7概述:所有端點的列表

下表總結了Spring Cloud網關執行器端點。請注意,每個端點都有/actuator/gateway作為基本路徑。

IDHTTP方法描述

globalfilters

GET

Displays the list of global filters applied to the routes.

routefilters

GET

Displays the list of GatewayFilter factories applied to a particular route.

refresh

POST

Clears the routes cache.

routes

GET

Displays the list of routes defined in the gateway.

routes/{id}

GET

Displays information about a particular route.

routes/{id}

POST

Add a new route to the gateway.

routes/{id}

DELETE

Remove an existing route from the gateway.

123.故障排除

123.1日志級別

以下是一些有用的記錄器,它們包含DEBUGTRACE級別的有價值的故障排除信息。

  • org.springframework.cloud.gateway
  • org.springframework.http.server.reactive
  • org.springframework.web.reactive
  • org.springframework.boot.autoconfigure.web
  • reactor.netty
  • redisratelimiter

123.2竊聽

Reactor Netty?HttpClientHttpServer可以啟用竊聽功能。與將reactor.netty日志級別設置為DEBUGTRACE結合使用時,將允許記錄信息,例如通過網絡發送和接收的標頭和正文。要啟用此功能,請分別為HttpServerHttpClient設置spring.cloud.gateway.httpserver.wiretap=true和/或spring.cloud.gateway.httpclient.wiretap=true

124.開發人員指南

這些是編寫網關的某些自定義組件的基本指南。

124.1編寫自定義路由謂詞工廠

為了編寫路由謂詞,您將需要實現RoutePredicateFactory。您可以擴展名為AbstractRoutePredicateFactory的抽象類。

MyRoutePredicateFactory.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> MyRoutePredicateFactory <span style="color:#7f0055"><strong>extends</strong></span> AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {<span style="color:#7f0055"><strong>public</strong></span> MyRoutePredicateFactory() {<span style="color:#7f0055"><strong>super</strong></span>(Config.<span style="color:#7f0055"><strong>class</strong></span>);}<em><span style="color:gray">@Override</span></em><span style="color:#7f0055"><strong>public</strong></span> Predicate<ServerWebExchange> apply(Config config) {<span style="color:#3f5f5f"><em>// grab configuration from Config object</em></span><span style="color:#7f0055"><strong>return</strong></span> exchange -> {<span style="color:#3f5f5f"><em>//grab the request</em></span>ServerHttpRequest request = exchange.getRequest();<span style="color:#3f5f5f"><em>//take information from the request to see if it</em></span><span style="color:#3f5f5f"><em>//matches configuration.</em></span><span style="color:#7f0055"><strong>return</strong></span> matches(config, request);};}<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>static</strong></span> <span style="color:#7f0055"><strong>class</strong></span> Config {<span style="color:#3f5f5f"><em>//Put the configuration properties for your filter here</em></span>}}</span></span></span>

124.2編寫自定義GatewayFilter工廠

為了編寫GatewayFilter,您將需要實現GatewayFilterFactory。您可以擴展名為AbstractGatewayFilterFactory的抽象類。

PreGatewayFilterFactory.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> PreGatewayFilterFactory <span style="color:#7f0055"><strong>extends</strong></span> AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {<span style="color:#7f0055"><strong>public</strong></span> PreGatewayFilterFactory() {<span style="color:#7f0055"><strong>super</strong></span>(Config.<span style="color:#7f0055"><strong>class</strong></span>);}<em><span style="color:gray">@Override</span></em><span style="color:#7f0055"><strong>public</strong></span> GatewayFilter apply(Config config) {<span style="color:#3f5f5f"><em>// grab configuration from Config object</em></span><span style="color:#7f0055"><strong>return</strong></span> (exchange, chain) -> {<span style="color:#3f5f5f"><em>//If you want to build a "pre" filter you need to manipulate the</em></span><span style="color:#3f5f5f"><em>//request before calling chain.filter</em></span>ServerHttpRequest.Builder builder = exchange.getRequest().mutate();<span style="color:#3f5f5f"><em>//use builder to manipulate the request</em></span><span style="color:#7f0055"><strong>return</strong></span> chain.filter(exchange.mutate().request(request).build());};}<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>static</strong></span> <span style="color:#7f0055"><strong>class</strong></span> Config {<span style="color:#3f5f5f"><em>//Put the configuration properties for your filter here</em></span>}}</span></span></span>

PostGatewayFilterFactory.java。?

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> PostGatewayFilterFactory <span style="color:#7f0055"><strong>extends</strong></span> AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {<span style="color:#7f0055"><strong>public</strong></span> PostGatewayFilterFactory() {<span style="color:#7f0055"><strong>super</strong></span>(Config.<span style="color:#7f0055"><strong>class</strong></span>);}<em><span style="color:gray">@Override</span></em><span style="color:#7f0055"><strong>public</strong></span> GatewayFilter apply(Config config) {<span style="color:#3f5f5f"><em>// grab configuration from Config object</em></span><span style="color:#7f0055"><strong>return</strong></span> (exchange, chain) -> {<span style="color:#7f0055"><strong>return</strong></span> chain.filter(exchange).then(Mono.fromRunnable(() -> {ServerHttpResponse response = exchange.getResponse();<span style="color:#3f5f5f"><em>//Manipulate the response in some way</em></span>}));};}<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>static</strong></span> <span style="color:#7f0055"><strong>class</strong></span> Config {<span style="color:#3f5f5f"><em>//Put the configuration properties for your filter here</em></span>}}</span></span></span>

124.3編寫自定義全局過濾器

為了編寫自定義全局過濾器,您將需要實現GlobalFilter接口。這會將過濾器應用于所有請求。

如何分別設置全局前置和后置過濾器的示例

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> GlobalFilter customGlobalFilter() {<span style="color:#7f0055"><strong>return</strong></span> (exchange, chain) -> exchange.getPrincipal().map(Principal::getName).defaultIfEmpty(<span style="color:#2a00ff">"Default User"</span>).map(userName -> {<span style="color:#3f5f5f"><em>//adds header to proxied request</em></span>exchange.getRequest().mutate().header(<span style="color:#2a00ff">"CUSTOM-REQUEST-HEADER"</span>, userName).build();<span style="color:#7f0055"><strong>return</strong></span> exchange;}).flatMap(chain::filter);
}<em><span style="color:gray">@Bean</span></em>
<span style="color:#7f0055"><strong>public</strong></span> GlobalFilter customGlobalPostFilter() {<span style="color:#7f0055"><strong>return</strong></span> (exchange, chain) -> chain.filter(exchange).then(Mono.just(exchange)).map(serverWebExchange -> {<span style="color:#3f5f5f"><em>//adds header to response</em></span>serverWebExchange.getResponse().getHeaders().set(<span style="color:#2a00ff">"CUSTOM-RESPONSE-HEADER"</span>,HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? <span style="color:#2a00ff">"It worked"</span>: <span style="color:#2a00ff">"It did not work"</span>);<span style="color:#7f0055"><strong>return</strong></span> serverWebExchange;}).then();
}</span></span></span>

125.使用Spring MVC或Webflux構建一個簡單的網關

[警告]

以下描述了替代樣式的網關。先前文檔的None適用于以下內容。

Spring Cloud Gateway提供了一個名為ProxyExchange的實用程序對象,您可以在常規的Spring web處理程序中將其用作方法參數。它通過鏡像HTTP動詞的方法支持基本的下游HTTP交換。使用MVC,它還支持通過forward()方法轉發到本地處理程序。要使用ProxyExchange,只需在類路徑中包含正確的模塊(spring-cloud-gateway-mvcspring-cloud-gateway-webflux)。

MVC示例(代理對遠程服務器下游“ /測試”的請求):

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@RestController</span></em>
<em><span style="color:gray">@SpringBootApplication</span></em>
<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> GatewaySampleApplication {<em><span style="color:gray">@Value("${remote.home}")</span></em><span style="color:#7f0055"><strong>private</strong></span> URI home;<em><span style="color:gray">@GetMapping("/test")</span></em><span style="color:#7f0055"><strong>public</strong></span> ResponseEntity<?> proxy(ProxyExchange<<span style="color:#7f0055"><strong>byte</strong></span>[]> proxy) <span style="color:#7f0055"><strong>throws</strong></span> Exception {<span style="color:#7f0055"><strong>return</strong></span> proxy.uri(home.toString() + <span style="color:#2a00ff">"/image/png"</span>).get();}}</span></span></span>

與Webflux相同:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@RestController</span></em>
<em><span style="color:gray">@SpringBootApplication</span></em>
<span style="color:#7f0055"><strong>public</strong></span> <span style="color:#7f0055"><strong>class</strong></span> GatewaySampleApplication {<em><span style="color:gray">@Value("${remote.home}")</span></em><span style="color:#7f0055"><strong>private</strong></span> URI home;<em><span style="color:gray">@GetMapping("/test")</span></em><span style="color:#7f0055"><strong>public</strong></span> Mono<ResponseEntity<?>> proxy(ProxyExchange<<span style="color:#7f0055"><strong>byte</strong></span>[]> proxy) <span style="color:#7f0055"><strong>throws</strong></span> Exception {<span style="color:#7f0055"><strong>return</strong></span> proxy.uri(home.toString() + <span style="color:#2a00ff">"/image/png"</span>).get();}}</span></span></span>

ProxyExchange上有一些便利的方法可以使處理程序方法發現并增強傳入請求的URI路徑。例如,您可能希望提取路徑的尾隨元素以將它們傳遞到下游:

<span style="color:#333333"><span style="color:#000000"><span style="background-color:#f8f8f8"><em><span style="color:gray">@GetMapping("/proxy/path/**")</span></em>
<span style="color:#7f0055"><strong>public</strong></span> ResponseEntity<?> proxyPath(ProxyExchange<<span style="color:#7f0055"><strong>byte</strong></span>[]> proxy) <span style="color:#7f0055"><strong>throws</strong></span> Exception {String path = proxy.path(<span style="color:#2a00ff">"/proxy/path/"</span>);<span style="color:#7f0055"><strong>return</strong></span> proxy.uri(home.toString() + <span style="color:#2a00ff">"/foos/"</span> + path).get();
}</span></span></span>

網關處理程序方法可以使用Spring MVC或Webflux的所有功能。因此,例如,您可以注入請求標頭和查詢參數,并且可以使用映射批注中的聲明來約束傳入的請求。有關這些功能的更多詳細信息,請參見Spring MVC中的@RequestMapping文檔。

可以使用ProxyExchange上的header()方法將標頭添加到下游響應中。

您還可以通過將映射器添加到get()等方法來操縱響應頭(以及響應中您喜歡的任何其他內容)。映射器是Function,它接收傳入的ResponseEntity并將其轉換為傳出的ResponseEntity

為不傳遞到下游的“敏感”標頭(默認情況下為“ cookie”和“授權”)以及“代理”標頭(x-forwarded-*)提供了一流的支持

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41143.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41143.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41143.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中的數據脫敏與隱私保護技術

Java中的數據脫敏與隱私保護技術 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 隨著信息化進程的加深&#xff0c;數據安全和隱私保護越來越受到關注。數據脫…

Python文件讀入操作

本套課在線學習視頻&#xff08;網盤地址&#xff0c;保存到網盤即可免費觀看&#xff09;&#xff1a; ??https://pan.quark.cn/s/e2ba7867f034?? Python編程中&#xff0c;文件操作是一項基礎且重要的技能。本文將詳細介紹如何使用Python進行文件的打開、讀取、寫入和關…

配置基于不同IP地址的虛擬主機

定義配置文件vhost.conf <directory /www> allowoverride none require all granted </directory> <virtualhost 192.168.209.136:80> documentroot /www servername 192.168.209.136 </virtualhost><virtualhost 192.168.209.138:80> document…

Restore Equipment

Restore Equipment 魔獸世界 - 盜號申請 - 恢復裝備流程 魔獸和網易真的不行啊 1&#xff09;這個裝備本來就是兌換的竟然可以賣NPC 2&#xff09;針對這個情況竟然無法挽回 3&#xff09;設計理念真的不得不吐槽一下 4&#xff09;策劃真的不咋樣&#xff0c;要是有機會我要自…

【C++】 解決 C++ 語言報錯:Stack Overflow

文章目錄 引言 棧溢出&#xff08;Stack Overflow&#xff09;是 C 編程中常見且嚴重的錯誤之一。棧溢出通常發生在程序遞歸調用過深或分配過大的局部變量時&#xff0c;導致棧空間耗盡。棧溢出不僅會導致程序崩潰&#xff0c;還可能引發不可預測的行為。本文將深入探討棧溢出…

Linux系統安裝青龍面板結合內網穿透實現使用公網地址遠程訪問

文章目錄 前言一、前期準備本教程環境為&#xff1a;Centos7&#xff0c;可以跑Docker的系統都可以使用。本教程使用Docker部署青龍&#xff0c;如何安裝Docker詳見&#xff1a; 二、安裝青龍面板三、映射本地部署的青龍面板至公網四、使用固定公網地址訪問本地部署的青龍面板 …

【帶你全面了解 RAG,深入探討其核心范式、關鍵技術及未來趨勢】

文末有福利&#xff01; 大型語言模型&#xff08;LLMs&#xff09;已經成為我們生活和工作的一部分&#xff0c;它們以驚人的多功能性和智能化改變了我們與信息的互動方式。 然而&#xff0c;盡管它們的能力令人印象深刻&#xff0c;但它們并非無懈可擊。這些模型可能會產生…

HY lisp quote unquote等學習

? 宏相關語法糖 This is all resolved at the reader level, so the model that gets produced is the same whether you take your code with sugar or without. Macro Syntax quote FORM quasiquote FORM unquote ~FORM unquote-splice ~FORM unpack-iterable …

昇思25天學習打卡營第16天 | DCGAN生成漫畫頭像

這兩天把minspore配置到我的電腦上了&#xff0c;然后運行就沒什么問題了?&#x1f60a; 今天學這個DCGAN生成漫畫頭像&#xff0c;我超級感興趣的嘞&#x1f984;&#x1f970; GAN基礎原理 這部分原理介紹參考GAN圖像生成。 DCGAN原理 DCGAN&#xff08;深度卷積對抗生成…

Python中的lambda函數是什么以及它有哪些用途和限制

Python中的lambda函數 定義 Python中的lambda函數是一種簡潔定義小函數的方式&#xff0c;也被稱為匿名函數。它允許用戶快速定義一個小的、一次性的函數對象&#xff0c;而無需正式地命名一個函數。lambda函數的基本語法為&#xff1a;lambda arguments: expression&#xf…

港三新二是那幾所大學?有哪些知名校友?中英雙語介紹

中文版 港三新二指的是香港和新加坡的五所著名大學&#xff0c;分別是香港大學&#xff08;HKU&#xff09;、香港中文大學&#xff08;CUHK&#xff09;、香港科技大學&#xff08;HKUST&#xff09;、新加坡國立大學&#xff08;NUS&#xff09;和南洋理工大學&#xff08;N…

秒驗—手機號碼置換接口

功能說明 提交客戶端獲取到的token、opToken等數據&#xff0c;驗證后返回手機號碼 服務端務必不要緩存DNS&#xff0c;否則可能影響服務高可用性 調用地址 POST https://identify-verify.dutils.com/auth/auth/sdkClientFreeLogin 請求頭 Content-Type &#xff1a;appli…

圖書商城系統java項目ssm項目jsp項目java課程設計java畢業設計

文章目錄 圖書商城系統一、項目演示二、項目介紹三、部分功能截圖四、部分代碼展示五、底部獲取項目源碼&#xff08;9.9&#xffe5;帶走&#xff09; 圖書商城系統 一、項目演示 圖書商城系統 二、項目介紹 語言: Java 數據庫&#xff1a;MySQL 技術棧&#xff1a;SpringS…

SaaS行業的AI化征程:穿越“大模型焦慮”,擁抱“AI自信”

隨著大模型技術的風起云涌&#xff0c;SaaS行業正站在一個充滿機遇與挑戰的十字路口。本文旨在深入剖析SaaS廠商在AI化升級過程中所遭遇的“大模型焦慮”&#xff0c;并探索通過戰略性的AI應用策略&#xff0c;如何重拾信心&#xff0c;實現產品與服務的華麗轉身&#xff0c;為…

關于虛擬機上不了網的解決辦法

先ping出ip地址 或者查詢ifconfig得到目前網絡信息 繼續輸入命令Ifconfig -a查詢是否能找到ip地址 明顯ens33是沒有打開的&#xff0c;所以找不到分配的ip地址&#xff0c;需要打開&#xff0c;自動隨機分配ip 輸入命令&#xff1a; sudo dhclient ens33 現在就可以開始上網…

公司“領導”們竟如此討論工作!小伙:此事有蹊蹺;|國家漏洞庫CNNVD:關于OpenSSH安全漏洞的通報;

公司“領導”們竟如此討論工作&#xff01;小伙&#xff1a;此事有蹊蹺 “當時我正在等驗證碼 還好你們快了一步 不然公司的93萬余元就沒了” 一談到這件事 杜先生仍然心有余悸 近日 正在處理公司財務工作的杜先生 突然被拉進了一個QQ群聊 從頭像、昵稱上看 群聊里的竟…

累積分布函數的一些性質證明

性質1&#xff1a; E [ X ] ∫ 0 ∞ ( 1 ? F ( x ) ) d x ? ∫ ? ∞ 0 F ( x ) d x ( 1 ) E[X]\int_0^{\infty}(1-F(x))dx - \int_{-\infty}^0F(x)dx\quad (1) E[X]∫0∞?(1?F(x))dx?∫?∞0?F(x)dx(1) 證明&#xff1a; E [ X ] ∫ ? ∞ ∞ x p ( x ) d x E[X] …

SpringBoot | 大新聞項目后端(redis優化登錄)

該項目的前篇內容的使用jwt令牌實現登錄認證&#xff0c;使用Md5加密實現注冊&#xff0c;在上一篇&#xff1a;http://t.csdnimg.cn/vn3rB 該篇主要內容&#xff1a;redis優化登錄和ThreadLocal提供線程局部變量&#xff0c;以及該大新聞項目的主要代碼。 redis優化登錄 其實…

macOS版ChatGPT更新:修復AI對話純文本存儲問題

貓頭虎 &#x1f42f; 建聯貓頭虎&#xff0c;商務合作&#xff0c;產品評測&#xff0c;產品推廣&#xff0c;個人自媒體創作&#xff0c;超級個體&#xff0c;漲粉秘籍&#xff0c;一起探索編程世界的無限可能&#xff01; macOS版ChatGPT更新&#xff1a;修復AI對話純文本…

HOW - React Router v6.x Feature 實踐(react-router-dom)

目錄 基本特性ranked routes matchingactive linksNavLinkuseMatch relative links1. 相對路徑的使用2. 嵌套路由的增強行為3. 優勢和注意事項4. . 和 ..5. 總結 data loadingloading or changing data and redirectpending navigation uiskeleton ui with suspensedata mutati…