特性
- 基於 Java 8 編碼
- 基於 Spring Framework 5 + Project Reactor + Spring Boot 2.0 構建
- 支持動態路由,能夠匹配任何請求屬性上的路由
- 支持內置到 Spring Handler 映射中的路由匹配
- 支持基於 HTTP 請求的路由匹配(Path、Method、Header、Host 等等)
- 集成了 Hystrix 斷路器
- 過濾器作用於匹配的路由
- 過濾器可以修改 HTTP 請求和 HTTP 響應(增加/修改 Header、增加/修改請求參數、改寫請求 Path 等等)
- 支持 Spring Cloud DiscoveryClient 配置路由,與服務發現與註冊配合使用
- 支持限流
引入
POM配置
<properties>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入 Spring Cloud Gateway 相關依賴,使用它作爲網關,並實現對其的自動配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
如果引入了starter,但是又不想讓gateway生效,可以設置
spring.cloud.gateway.enabled=false
Spring cloud gateway構建於spring boot 2.x,spring webflux,reactor。需要spring webfluxr提供的netty運行環境,不能使用傳統的servlet容器或者構建成WAR包。
術語
Route
Route 是 gateway 中最基本的組件之一,表示一個具體的路由信息載體。
Route 主要定義瞭如下幾個部分:
① id,標識符,區別於其他 Route。
② destination uri,路由指向的目的地 uri,即客戶端請求最終被轉發的目的地。
③ order,用於多個 Route 之間的排序,數值越小排序越靠前,匹配優先級越高。
④ predicate,謂語,表示匹配該 Route 的前置條件,即滿足相應的條件纔會被路由到目的地 uri。
⑤ gateway filters,過濾器用於處理切面邏輯,如路由轉發前修改請求頭等。
Predicate
Predicate 即 Route 中所定義的部分,用於條件匹配。
參考 Java 8 提供的 Predicate 和 Function,輸入類型是Spring Framework ServerWebExchange,可以匹配HTTP請求的任何信息,例如headers,cookies,parameters
Filter
Filter 最終是通過 filter chain 來形成鏈式調用的,每個 filter 處理完 pre filter 邏輯後委派給 filter chain,filter chain 再委派給下一下 filter。
怎麼工作
① Gateway 接收客戶端請求。
② 客戶端請求與路由信息進行匹配,匹配成功的才能夠被髮往相應的下游服務。
③ 請求經過 Filter 過濾器鏈,執行 pre 處理邏輯,如修改請求頭信息等。
④ 請求被轉發至下游服務並返回響應。
⑤ 響應經過 Filter 過濾器鏈,執行 post 處理邏輯。
⑥ 向客戶端響應應答。
配置Route Predicate Factories和Gateway Filter Factories
快捷方式
Filter名稱後跟等號(=),後跟以逗號分開的參數
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
完整方式
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
Route Predicate Factories
Spring Cloud Gateway使用Handler Mapping來確定Route,內部指定了很多predicate Factories用於匹配HTTP請求的不同屬性。
可以通過and語句來合併多個route predicate。
- After:匹配時間晚於指定日期的HTTP請求。
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
- Before:匹配時間早於指定日期的HTTP請求。
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
- Between:匹配時間介於指定日期範圍的HTTP請求。
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
- Cookie:匹配包含指定cookie名稱和值(regex,java正則表達式)的HTTP請求。
predicates:
- Cookie=chocolate, ch.p
- Header:匹配包含指定header名稱和值(regex,java正則表達式)的HTTP請求。
predicates:
- Header=X-Request-Id, \d+
- Host:匹配指定host。
predicates:
- Host=**.somehost.org,**.anotherhost.org
- Method:匹配指定method
predicates:
- Method=GET,POST
- Path:匹配路徑,支持Url 模板。
predicates:
- Path=/red/{segment},/blue/{segment}
- Query:如果包含指定查詢參數(參數名稱或可選的regex),則匹配。
predicates:
- Query=green
- RemoteAddr:匹配遠程地址
predicates:
- RemoteAddr=192.168.1.1/24
- Weight : 權重路由,用於實現了負載均衡的情況。
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
默認情況下,RemoteAddr 使用進入的請求獲取RemoteAddr。如果gateway在一個代理層後,則有可能獲取不到真實的IP。
可以指定一個Resolver自定義RemoteAddressResolver,來解析RemoteAddr,Gateway實現了一個非默認的基於 X-Forwarded-For header的XForwardedRemoteAddressResolver。
GatewayFilter Factories
Route Filters用於修改進入的HTTP Request和返回的HTTP Response。
AddRequestHeader
:增加Request Header,可識別PATH或HOST中的變量。
filters:
- AddRequestHeader=X-Request-red, blue
AddRequestParameter
:增加request parameter到query string,可識別PATH或HOST中的變量。
filters:
- AddRequestParameter=color, blue
AddResponseHeader
:增加Reponse Header,可識別PATH或HOST中的變量。
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
- DedupeResponseHeader :剔除響應頭中重複的值,需要去重的Header名稱及去重策略(可選)。
去重策略:
- RETAIN_FIRST:默認值,保留第一個值
- RETAIN_LAST:保留最後一個值
- RETAIN_UNIQUE:保留所有唯一值,以它們第一次出現的順序保留
filters:
# 若需要去重的Header有多個,使用空格分隔
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
Hystrix
:爲路由引入Hystrix的斷路器保護
Hystrix是Spring Cloud第一代容錯組件,不過已經進入維護模式,未來Hystrix會被Spring Cloud移除掉,取而代之的是Alibaba Sentinel/Resilience4J。
filters:
- Hystrix=myCommandName
或者
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
- CircuitBreaker:建議使用Resilience4J
filters:
- CircuitBreaker=myCircuitBreaker
FallbackHeaders
:爲fallbackUri的請求頭中添加具體的異常信息
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
MapRequestHeader
:從已存在header中獲取值,新增一個header(fromHeader,toHeader)
filters:
- MapRequestHeader=Blue, X-Request-Red
-
PrefixPath
:爲原始請求路徑添加前綴
filters:
- PrefixPath=/mypath
PreserveHostHeader
:爲請求添加一個preserveHostHeader=true的屬性,路由過濾器會檢查該屬性以決定是否要發送原始的Host
filters:
- PreserveHostHeader
RequestRateLimiter
:用於對請求限流,限流算法爲令牌桶
參數:keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
redisRateLimiter
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
RedirectTo
:將原始請求重定向到指定的URL。參數:http狀態碼及重定向的url
filters:
- RedirectTo=302, https://acme.org
RemoveRequestHeader
:爲原始請求刪除某個Header,參數:header名稱
filters:
- RemoveRequestHeader=X-Request-Foo
RemoveResponseHeader
:爲原始響應刪除某個Header,參數:header名稱
filters:
- RemoveResponseHeader=X-Response-Foo
RemoveRequestParameter
:爲原始請求刪除某個parameter,參數:parameter名稱
filters:
- RemoveRequestParameter=red
RewritePath
:重寫原始的請求路徑 ,參數:原始路徑正則表達式以及重寫後路徑的正則表達式。$\替換$,不然表示變量。
#正則表達式 替換
filters:
- RewritePath=/red(?<segment>/?.*), $\{segment}
RewriteLocationResponseHeader
:重寫Location響應header的值。參數:stripVersionMode
, locationHeaderName
, hostValue
, and protocolsRegex。
stripVersionMode的值:
NEVER_STRIP
即使原始請求路徑不包含任何版本,也不會剝離版本。AS_IN_REQUEST
僅當原始請求不包含版本時,版本纔會被剝離。ALWAYS_STRIP
即使原始請求路徑包含版本,也會刪除版本。
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
RewriteResponseHeader
:正則表達式重寫響應頭的值。參數:name
,regexp
和replacement
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*
SaveSession
:強制執行WebSession::save
操作
filters:
- SaveSession
SecureHeaders:
添加了許多頭到響應中。
- 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命令空間修改。
要禁用yixie值,可以通過spring.cloud.gateway.filter.secure-headers.disable設置,用逗號分開
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
SetPath
:採用路徑template
參數。通過允許路徑的模板片段,提供了一種操作請求路徑的簡單方法
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
SetRequestHeader
:設置請求header的值
filters:
- SetRequestHeader= username,admin
SetResponseHeader
:
filters:
- SetResponseHeader=X-Response-Red, Blue
-
SetStatus
:設置響應狀態。status
, 必須是一個有效的SpringHttpStatus
. 它可以是整數值404
或是枚舉的字符串表示形式NOT_FOUND
filters:
- SetStatus=401
StripPrefix
:切除請求路徑前綴,參數:切除多少段(以/分割)
predicates:
- Path=/name/**
filters:
#可以將/user/name/stripPrefix 地址 切除前面兩段,所以最後轉發到下游的地址是/stripPrefix
- StripPrefix=2
Retry
:重試設置
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
RequestSize
:限制請求大小。
filters:
- name: RequestSize
args:
#默認爲B,可以設置爲KB,MB
maxSize: 5000000
SetRequestHost
:重寫host
filters:
- name: SetRequestHost
args:
host: example.org
-
ModifyRequestBody
:將請求體進行修改。
只能通過java代碼設置。
ModifyResponseBody
:對響應體進行修改
只支持Java配置。
- Default:通過spring.cloud.gateway.default-filters 設置默認filters。
pring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
參考
官方文檔:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/