Spring Cloud Gateway源碼導(dǎo)讀

Spring Cloud Gateway源碼導(dǎo)讀:

首先我們觀察在引入了Spring Cloud Gateway后自動裝配都做了什么?從Spring Cloud Gateway包下找到spring.factories赘风,查看EnableAutoConfiguration項即,仔細(xì)觀察后不難發(fā)現(xiàn)關(guān)鍵配置項即為GatewayAutoConfigurationGatewayReactiveLoadBalancerClientAutoConfiguration(需要配合spring-cloud-loadbalancer一起使用)括改。
那么我們分別來看看這兩個配置類都做了什么错邦。

GatewayAutoConfiguration

該配置類中主要裝配了如下幾種類型的對象:

  • RouteDefinitionLocator(Properties)
  • RouteDefinitionRepository(Redis探赫、InMemory)
  • RouteLocator(RouteDefinition)
  • RouteRefreshListener
  • HandlerMapping(RoutePredicateHandlerMapping)
  • WebHandler(FilteringWebHandler)
  • GlobalFilters
  • Predicate Factory Beans
  • GatewayFilter Factory Beans

下面我們依次介紹上述各對象的作用

RouteDefinitionLocator

可以將名稱拆開看,即RouteDefinitionLocator撬呢,其中RouteDefinitionSpring Beans中的BeanDefinition類似期吓,從名字上也能看出其實就是用來定義Route的,用來記錄Route的關(guān)鍵屬性倾芝,例如Predicates讨勤、Filtersurl等晨另。

Locator則是用來從特定的位置讀取RouteDefinition潭千,目前Spring Cloud Gateway默認(rèn)是從Properties來讀取RouteDefinition。讀取后交給RouteLocator實例化為Route對象借尿。

RouteDefinitionRepository

Spring Cloud Gateway提供InMemory刨晴、Redis等的RouteDefinitionRepository,主要用來動態(tài)添加RouteDefinition路翻,需要注意的是InMemory通常在Spring Actuator中打開routes端點即可使用狈癞,在添加成功后需要發(fā)出RouteRefresh事件即可更新內(nèi)存中的路由。

RouteLocator

默認(rèn)為RouteDefinitionRouteLocator茂契,主要作用是根據(jù)RouteDefinitionLocator中返回的RouteDefinition創(chuàng)建Route對象蝶桶,核心操作是將RouteDefinition中定義的Predicate FactoryFilter Factory實例化掉冶,最終封裝在Route對象中真竖,以供請求進(jìn)來時篩選路由脐雪。

RouteRefreshListener

路由發(fā)生更新時需要發(fā)布RouteRefresh事件,該監(jiān)聽器負(fù)責(zé)更新內(nèi)存中的路由列表恢共。

HandlerMapping

當(dāng)DispatcherHandler分發(fā)請求時調(diào)用HandlerMapping.getHandler方法來獲取HandlerAdapter以供后續(xù)鏈?zhǔn)秸{(diào)用战秋,Spring Cloud Gateway默認(rèn)是由RoutePredicateHandlerMapping處理。在該處理器繼承自AbstractHandlerMapping讨韭,并實現(xiàn)抽象方法getHandlerInternal脂信。當(dāng)有請求進(jìn)來時,通過lookupRoute尋找內(nèi)存中所有的Route透硝,并通過路由的Predicate尋找與當(dāng)前請求相匹配的路由狰闪,將其放進(jìn)exchange后,最終返回FilteringWebHandler蹬铺。

WebHandler

當(dāng)DispatcherHandlerHandlerMapping中獲取到了HandlerAdapter后,隨即立即調(diào)用HandlerAdapter來處理請求秉撇,上述RoutePredicateHandlerMapping返回的FilteringWebHandler是一種WebHandler甜攀,由SimpleHandlerAdapter負(fù)責(zé)處理,在FilteringWebHandler中會將Global FiltersRoute中定義的Gateway Filters合并琐馆,按照Order排序后封裝成DefaultGatewayFilterChain依次后調(diào)用filter方法规阀。

GlobalFilters

在純Spring Cloud Gateway環(huán)境下存在9個全局過濾器,他們按照執(zhí)行順序分別是:

名稱 Order 作用
RemoveCachedBodyFilter Integer.MIN_VALUE
AdaptCachedBodyGlobalFilter Integer.MIN_VALUE + 1000
NettyWriteResponseFilter -1 用來寫響應(yīng)給客戶端
ForwardPathFilter 0 若Route中定義的uri是forward類型瘦麸,則將exchange中的request修改為forward類型谁撼。
RouteToRequestUrlFilter 10000 取出Route中定義的uri,將其設(shè)置在exchange中
NoLoadBalancerClientFilter 10150 在GatewayNoLoadBalancerClientAutoConfiguration中定義滋饲,不使用loadBalance厉碟。
WebsocketRoutingFilter Integer.MAX_VALUE - 1 從exchange中取出RouteToRequestUrlFilter中設(shè)置的uri,處理websocket協(xié)議下的路由
NettyRoutingFilter Integer.MAX_VALUE 從exchange中取出RouteToRequestUrlFilter中設(shè)置的uri屠缭,處理http箍鼓、https協(xié)議下的路由,主要作用是創(chuàng)建新的httpclient呵曹,根據(jù)uri發(fā)送請求并增加request及response處理款咖,同時超時處理也在這個位置。
ForwardRoutingFilter Integer.MAX_VALUE 如果是forward類型請求奄喂,則交給dispatcherhandler重新處理铐殃。

Predicate Factory Beans

內(nèi)置的Predicate工廠處理類,用來根據(jù)RouteDefinition中的配置生成對應(yīng)的Predicate跨新。在HandlerMapping中通過調(diào)用Predicate.test方法匹配請求與路由富腊。

PS.這里有個性能瓶頸,默認(rèn)策略是循環(huán)遍歷每一個路由的Predicate.test方法進(jìn)行匹配域帐,當(dāng)路由數(shù)量越來越多時性能急劇下降蟹肘,可根據(jù)實際業(yè)務(wù)中路由的Predicate類型進(jìn)行優(yōu)化词疼。例如全都是PathRoutePredicate時,可根據(jù)固有邏輯建立路由標(biāo)識與路由的緩存帘腹,在請求進(jìn)來時快速查找贰盗,找不到時由默認(rèn)邏輯兜底。

GatewayFilter Factory Beans

內(nèi)置的路由級別GatewayFilter工廠處理類阳欲,用來根據(jù)RouteDefinition中的配置生成對應(yīng)的GatewayFilter舵盈。在

FilteringWebHandler中會與GlobalFilter合并后對請求進(jìn)行處理。

GatewayReactiveLoadBalancerClientAutoConfiguration

當(dāng)引入了spring-cloud-loadbalancer后球化,該配置類會自動注入ReactiveLoadBalancerClientFilter從而替代默認(rèn)的NoLoadBalancerClientFilter秽晚。當(dāng)前版本的Spring Cloud Gateway原生支持RandomRoundRobin兩種負(fù)載策略筒愚,默認(rèn)使用RoundRobin策略赴蝇。

注意,ReactiveLoadBalancerClientFilterOrderNoLoadBalancerClientFilter相同巢掺,都為10150句伶。

ReactiveLoadBalancerClientFilter的處理流程

ReactiveLoadBalancerClientFilter在處理時僅處理lb://類型的uri,其原理為從uri中解析出的host后陆淀,通過利用NamedContextFactory創(chuàng)建一個新的以Route idnameApplicationContext考余,由LoadBalancerClientConfiguration自動注入RoundRobinLoadBalancer到新建的ApplicationContext中,隨后通過LoadBalancerServiceInstanceListSupplier中查找出指定host的所有實例轧苫,根據(jù)負(fù)載均衡算法選取一個示例后返回給ReactiveLoadBalancerClientFilter楚堤,接著將實例的uri與原有請求的uri合并后替換exchange中的GATEWAY_REQUEST_URL_ATTR以供后續(xù)NettyRoutingFilter使用。
大體上的Spring Cloud Gateway的初始化及處理流程就是這樣含懊,至于每個Filter的細(xì)節(jié)可以根據(jù)項目中使用到的情況來繼續(xù)研讀身冬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市岔乔,隨后出現(xiàn)的幾起案子吏恭,更是在濱河造成了極大的恐慌,老刑警劉巖重罪,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件樱哼,死亡現(xiàn)場離奇詭異,居然都是意外死亡剿配,警方通過查閱死者的電腦和手機(jī)搅幅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呼胚,“玉大人茄唐,你說我怎么就攤上這事。” “怎么了沪编?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵呼盆,是天一觀的道長。 經(jīng)常有香客問我蚁廓,道長访圃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任相嵌,我火速辦了婚禮腿时,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饭宾。我一直安慰自己批糟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布看铆。 她就那樣靜靜地躺著徽鼎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弹惦。 梳的紋絲不亂的頭發(fā)上否淤,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音肤频,去河邊找鬼叹括。 笑死算墨,一個胖子當(dāng)著我的面吹牛宵荒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播净嘀,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼报咳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挖藏?” 一聲冷哼從身側(cè)響起暑刃,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膜眠,沒想到半個月后岩臣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡宵膨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年架谎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辟躏。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡谷扣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捎琐,到底是詐尸還是另有隱情会涎,我是刑警寧澤裹匙,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站末秃,受9級特大地震影響概页,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛔溃,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一绰沥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贺待,春花似錦徽曲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哪工,卻和暖如春奥此,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雁比。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工稚虎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人偎捎。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓蠢终,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茴她。 傳聞我的和親對象是個殘疾皇子寻拂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容