本系列向大家簡單介紹下 Spring Cloud Gateway (2.1.1.RELEASE) 的基本概念、簡單應用和基本原理, 由於篇幅較長,將分拆成兩個小節, 具體如下:
話不多說,直接開幹!
基本組成
spring cloud gateway 由以下三部分造成:
- Route。網關的基本單位,由 ID、 URI、 一組 Predicate、 一組 Filter 組成, 根據 Predicate 進行匹配轉發。
- Predicate。路由轉發的判斷條件。 其接一個 ServerWebExchange 參數常見的有: Path/Query/Method/Header。
- Filter。路由轉發請求時所經過的過濾邏輯, 可用於修改請求、 響應內容。
工作原理
- Gateway 統一接收客戶端請求;
- 客戶端請求與路由信息進行匹配, 匹配成功的才能夠被髮往響應的下游服務;
- 請求經過 Filter 過濾器鏈, 執行 pre 處理方法, 做一些通用處理, 如添加或修改請求頭信息, 安全驗證等;
- 請求被轉發至下游服務並返回響應;
- 響應經過 Filter 過濾器鏈, 執行 post 處理邏輯;
- 返回響應信息至客戶端。
路由(Route)
基本概念
Route 是 Gateway 中最基本的組件之一, 表示一個具體的路由信息載體。 主要有以下幾個部分組成:
- id。 唯一標識符, 用於區別於其他 Route;
- uri。 路由指向的目的 uri。 即客戶端請求最終被轉發的目的地;
- order。 用於多個 Route 之間的排序, 數值越小排序越靠前, 匹配優先級越高;
- predicate。 謂詞, 表示匹配該 Route 的前置條件, 即滿足相應的條件才會被路由到目的地 url
- filters。 網關過濾器, 過濾器用於處理切面邏輯, 如路由轉發前修改請求頭等。
應用
外部化構建 Route
Spring Cloud Gateway 提供了一些開箱即用的 Predicate 和 Filter, 它們通過工廠模式來生產。 如下
<code>spring:
cloud:
gateway:
routes:
-
id:
helloWorld
uri:lb://hello-world-service
predicates:#
聲明
predicates,即請求滿足相應的條件才能匹配成功。
-
Header=X-Request-Id,
\d+
filters:
-
AddRequestHeader=X-Request-From,
Bumblebee
/<code>
編程方式構建 Route
編程的方式來定義 Route 會更加靈活。 主要是通過 fluent API RouteLocatorBuilder 來構建 RouteLocator, 具體代碼參考如下:
<code>public
RouteLocatorcustomRouteLocator
(RouteLocatorBuilder builder)
{return
builder.routes() .route(r -> r.host("**.for.bar"
).and().path("/abc/def"
) .filters(f -> f.addResponseHeader("X-TestHeader"
,"foobar"
)) .uri("http://httpbin.org:80"
) ) .build(); } /<code>
外部化配置完全是個黑盒, 通過編程的方式需要使用 Gateway 的 api, 靠近白盒。
原理
對於外部化構建方式, 基於 Spring boot 遵循約定大於配置的原則, starter 模塊都有對應的自動裝配類(AutoConfiguration) , 還有以模塊名為前綴, 以 Properties 後綴的配置類作為支持。 對於 Spring Cloud Gateway , GatewayProperties 就是其模塊的外部化配置類。 相關源碼如下:
<code> ("spring.cloud.gateway"
)public
class
GatewayProperties {private
List routes =new
ArrayList<>();private
List defaultFilters =new
ArrayList<>(); } /<code>
源碼中配置網關路由屬性,涉及到兩個類, RouteDefinition 和 FilterDefinition. 其中 RouteDefinition 用來對 Route 信息進行定義, 最終會被 RouteLocator 解析成 Route; FilterDefinition 用來定義 Filter。具體類中涉及到的屬性, 可以通過源碼獲取。 此處特別說明下有關 FilterDefinition 和 PredicateDefinition(RouteDefinition 中的屬性) 的構造方法, 以下以 FilterDefinition 為例分析源碼, 其構造方法相關的代碼如下:
<code>public
class
FilterDefinition {private
String
name;private
Map<String
,String
> args =new
LinkedHashMap<>(); /<code>
以配置 AddRequestHeader=X-Request-From, Bumblebee 說明上面代碼片段。 首先該配置使用的是 public FilterDeifinition(String text) 構造方法構建對象。 如果配置中無 =, 則直接設置 Filter 的名稱, 否則 第一個 = 前的為 Filter 的名稱, 後面的為該 Filter 的參數, 參數 , 分隔, 設置到參數 Map 中, key 為 "genkey" + i (此處不展開, 由 NameUtils 生成, 詳細可跟蹤 NameUtils 方法), value 為配置的值。
以上為 Spring Cloud Gateway 的第一篇,第二篇將為大家介紹「斷言和過濾器」,點此跳轉
關鍵字: Cloud 配置 FilterDefinition