java B2B2C Springcloud多租戶電子商城系統(tǒng)-Zuul過濾器詳解

過濾器是Zuul實(shí)現(xiàn)API網(wǎng)關(guān)功能最為核心的部件曹体,每一個(gè)進(jìn)入Zuul的HTTP請(qǐng)求都會(huì)經(jīng)過一系列的過濾器處理鏈得到請(qǐng)求響應(yīng)并返回給客戶端名船。
在Spring Cloud Zuul中實(shí)現(xiàn)的過濾器必須包含4個(gè)基本特征:過濾類型斩箫、執(zhí)行順序、執(zhí)行條件栋齿、具體操作再榄,這四個(gè)操作就是IZuulFilter接口以及ZuulFilter抽象類(ZuulFilter實(shí)現(xiàn)了IZuulFilter)和中定義的四個(gè)抽象方法:
需要JAVA Spring Cloud大型企業(yè)分布式微服務(wù)云構(gòu)建的B2B2C電子商務(wù)平臺(tái)源碼String filterType();

int filterOrder();

boolean shouldFilter();

Object run();
它們各自的含義與功能總結(jié)如下:

filterType:該函數(shù)需要返回一個(gè)字符串來代表過濾器的類型狡刘,而這個(gè)類型就是在HTTP請(qǐng)求過程中定義的各個(gè)階段。在Zuul中默認(rèn)定義了四種不同生命周期的過濾器類型困鸥,具體如下:
pre:可以在請(qǐng)求被路由之前調(diào)用嗅蔬。
routing:在路由請(qǐng)求時(shí)候被調(diào)用。
post:在routing和error過濾器之后被調(diào)用疾就。
error:處理請(qǐng)求時(shí)發(fā)生錯(cuò)誤時(shí)被調(diào)用澜术。
filterOrder:通過int值來定義過濾器的執(zhí)行順序,數(shù)值越小優(yōu)先級(jí)越高猬腰。
shouldFilter:返回一個(gè)boolean類型來判斷該過濾器是否要執(zhí)行鸟废。我們可以通過此方法來指定過濾器的有效范圍。
run:過濾器的具體邏輯姑荷。在該函數(shù)中盒延,我們可以實(shí)現(xiàn)自定義的過濾邏輯,來確定是否要攔截當(dāng)前的請(qǐng)求鼠冕,不對(duì)其進(jìn)行后續(xù)的路由添寺,或是在請(qǐng)求路由返回結(jié)果之后,對(duì)處理結(jié)果做一些加工等懈费。

核心過濾器
在Spring Cloud Zuul中计露,為了讓API網(wǎng)關(guān)組件可以更方便的上手使用,它在HTTP請(qǐng)求生命周期的各個(gè)階段默認(rèn)地實(shí)現(xiàn)了一批核心過濾器,它們會(huì)在API網(wǎng)關(guān)服務(wù)啟動(dòng)的時(shí)候被自動(dòng)地加載和啟用薄坏。我們可以在源碼中查看和了解它們趋厉,它們定義于spring-cloud-netflix-core模塊的org.springframework.cloud.netflix.zuul.filters包下。

pre過濾器

ServletDetectionFilter:它的執(zhí)行順序?yàn)?3胶坠,是最先被執(zhí)行的過濾器君账。該過濾器總是會(huì)被執(zhí)行,主要用來檢測(cè)當(dāng)前請(qǐng)求是通過Spring的DispatcherServlet處理運(yùn)行沈善,還是通過ZuulServlet來處理運(yùn)行的乡数。它的檢測(cè)結(jié)果會(huì)以布爾類型保存在當(dāng)前請(qǐng)求上下文的isDispatcherServletRequest參數(shù)中,這樣在后續(xù)的過濾器中闻牡,我們就可以通過RequestUtils.isDispatcherServletRequest()和RequestUtils.isZuulServletRequest()方法判斷它以實(shí)現(xiàn)做不同的處理净赴。一般情況下,發(fā)送到API網(wǎng)關(guān)的外部請(qǐng)求都會(huì)被Spring的DispatcherServlet處理罩润,除了通過/zuul/路徑訪問的請(qǐng)求會(huì)繞過DispatcherServlet玖翅,被ZuulServlet處理,主要用來應(yīng)對(duì)處理大文件上傳的情況割以。另外金度,對(duì)于ZuulServlet的訪問路徑/zuul/,我們可以通過zuul.servletPath參數(shù)來進(jìn)行修改严沥。

Servlet30WrapperFilter:它的執(zhí)行順序?yàn)?2猜极,是第二個(gè)執(zhí)行的過濾器。目前的實(shí)現(xiàn)會(huì)對(duì)所有請(qǐng)求生效消玄,主要為了將原始的HttpServletRequest包裝成Servlet30RequestWrapper對(duì)象跟伏。

FormBodyWrapperFilter:它的執(zhí)行順序?yàn)?1,是第三個(gè)執(zhí)行的過濾器翩瓜。該過濾器僅對(duì)兩種類請(qǐng)求生效受扳,第一類是Content-Type為application/x-www-form-urlencoded的請(qǐng)求,第二類是Content-Type為multipart/form-data并且是由Spring的DispatcherServlet處理的請(qǐng)求(用到了ServletDetectionFilter的處理結(jié)果)奥溺。而該過濾器的主要目的是將符合要求的請(qǐng)求體包裝成FormBodyRequestWrapper對(duì)象辞色。

DebugFilter:它的執(zhí)行順序?yàn)?,是第四個(gè)執(zhí)行的過濾器浮定。該過濾器會(huì)根據(jù)配置參數(shù)zuul.debug.request和請(qǐng)求中的debug參數(shù)來決定是否執(zhí)行過濾器中的操作相满。而它的具體操作內(nèi)容則是將當(dāng)前的請(qǐng)求上下文中的debugRouting和debugRequest參數(shù)設(shè)置為true。由于在同一個(gè)請(qǐng)求的不同生命周期中桦卒,都可以訪問到這兩個(gè)值立美,所以我們?cè)诤罄m(xù)的各個(gè)過濾器中可以利用這兩值來定義一些debug信息,這樣當(dāng)線上環(huán)境出現(xiàn)問題的時(shí)候方灾,可以通過請(qǐng)求參數(shù)的方式來激活這些debug信息以幫助分析問題建蹄。另外碌更,對(duì)于請(qǐng)求參數(shù)中的debug參數(shù),我們也可以通過zuul.debug.parameter來進(jìn)行自定義洞慎。

PreDecorationFilter:它的執(zhí)行順序?yàn)?痛单,是pre階段最后被執(zhí)行的過濾器。該過濾器會(huì)判斷當(dāng)前請(qǐng)求上下文中是否存在forward.to和serviceId參數(shù)劲腿,如果都不存在旭绒,那么它就會(huì)執(zhí)行具體過濾器的操作(如果有一個(gè)存在的話,說明當(dāng)前請(qǐng)求已經(jīng)被處理過了焦人,因?yàn)檫@兩個(gè)信息就是根據(jù)當(dāng)前請(qǐng)求的路由信息加載進(jìn)來的)挥吵。而它的具體操作內(nèi)容就是為當(dāng)前請(qǐng)求做一些預(yù)處理,比如:進(jìn)行路由規(guī)則的匹配花椭、在請(qǐng)求上下文中設(shè)置該請(qǐng)求的基本信息以及將路由匹配結(jié)果等一些設(shè)置信息等忽匈,這些信息將是后續(xù)過濾器進(jìn)行處理的重要依據(jù),我們可以通過RequestContext.getCurrentContext()來訪問這些信息矿辽。另外丹允,我們還可以在該實(shí)現(xiàn)中找到一些對(duì)HTTP頭請(qǐng)求進(jìn)行處理的邏輯,其中包含了一些耳熟能詳?shù)念^域嗦锐,比如:X-Forwarded-Host嫌松、X-Forwarded-Port沪曙。另外奕污,對(duì)于這些頭域的記錄是通過zuul.addProxyHeaders參數(shù)進(jìn)行控制的,而這個(gè)參數(shù)默認(rèn)值為true液走,所以Zuul在請(qǐng)求跳轉(zhuǎn)時(shí)默認(rèn)地會(huì)為請(qǐng)求增加X-Forwarded-*頭域碳默,包括:X-Forwarded-Host、X-Forwarded-Port缘眶、X-Forwarded-For嘱根、X-Forwarded-Prefix、X-Forwarded-Proto巷懈。我們也可以通過設(shè)置zuul.addProxyHeaders=false關(guān)閉對(duì)這些頭域的添加動(dòng)作该抒。

注意:在Spring Cloud系列(二十四) 路由詳解(Finchley.RC2版本)文中提到了忽略把敏感頭信息過濾掉的操作就是在PreDecorationFilter中執(zhí)行的。

route過濾器

RibbonRoutingFilter:它的執(zhí)行順序?yàn)?0顶燕,是route階段第一個(gè)執(zhí)行的過濾器凑保。該過濾器只對(duì)請(qǐng)求上下文中存在serviceId參數(shù)的請(qǐng)求進(jìn)行處理,即只對(duì)通過serviceId配置路由規(guī)則的請(qǐng)求生效涌攻。而該過濾器的執(zhí)行邏輯就是面向服務(wù)路由的核心欧引,它通過使用Ribbon和Hystrix來向服務(wù)實(shí)例發(fā)起請(qǐng)求,并將服務(wù)實(shí)例的請(qǐng)求結(jié)果返回恳谎。
SimpleHostRoutingFilter:它的執(zhí)行順序?yàn)?00芝此,是route階段第二個(gè)執(zhí)行的過濾器憋肖。該過濾器只對(duì)請(qǐng)求上下文中存在routeHost參數(shù)的請(qǐng)求進(jìn)行處理,即只對(duì)通過url配置路由規(guī)則的請(qǐng)求生效婚苹。而該過濾器的執(zhí)行邏輯就是直接向routeHost參數(shù)的物理地址發(fā)起請(qǐng)求岸更,從源碼中我們可以知道該請(qǐng)求是直接通過httpclient包實(shí)現(xiàn)的,而沒有使用Hystrix命令進(jìn)行包裝膊升,所以這類請(qǐng)求并沒有線程隔離和斷路器的保護(hù)坐慰。
SendForwardFilter:它的執(zhí)行順序?yàn)?00,是route階段第三個(gè)執(zhí)行的過濾器用僧。該過濾器只對(duì)請(qǐng)求上下文中存在forward.to參數(shù)的請(qǐng)求進(jìn)行處理结胀,即用來處理路由規(guī)則中的forward本地跳轉(zhuǎn)配置。

post過濾器

LocationRewriteFilter:它的執(zhí)行順序是900责循,于重定向時(shí)糟港,負(fù)責(zé)將標(biāo)頭重寫為Zuul的URL,否則院仿,瀏覽器會(huì)重定向到Web應(yīng)用程序的URL而不是Zuul URL秸抚。
SendResponseFilter:它的執(zhí)行順序?yàn)?000,是post階段最后執(zhí)行的過濾器歹垫。該過濾器會(huì)檢查請(qǐng)求上下文中是否包含請(qǐng)求響應(yīng)相關(guān)的頭信息剥汤、響應(yīng)數(shù)據(jù)流或是響應(yīng)體,只有在包含它們其中一個(gè)的時(shí)候就會(huì)執(zhí)行處理邏輯排惨。而該過濾器的處理邏輯就是利用請(qǐng)求上下文的響應(yīng)信息來組織需要發(fā)送回客戶端的響應(yīng)內(nèi)容吭敢。

error過濾器

SendErrorFilter:它的執(zhí)行順序?yàn)?,是post階段第一個(gè)執(zhí)行的過濾器暮芭。該過濾器僅在請(qǐng)求上下文中包含error.status_code參數(shù)(由之前執(zhí)行的過濾器設(shè)置的錯(cuò)誤編碼)并且還沒有被該過濾器處理過的時(shí)候執(zhí)行鹿驼。而該過濾器的具體邏輯就是利用請(qǐng)求上下文中的錯(cuò)誤信息來組織成一個(gè)forward到API網(wǎng)關(guān)/error錯(cuò)誤端點(diǎn)的請(qǐng)求來產(chǎn)生錯(cuò)誤響應(yīng)。電子商務(wù)社交平臺(tái)源碼請(qǐng)加企鵝求求:三五三六二四七二五九

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辕宏,一起剝皮案震驚了整個(gè)濱河市畜晰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瑞筐,老刑警劉巖凄鼻,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異聚假,居然都是意外死亡块蚌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門魔策,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匈子,“玉大人,你說我怎么就攤上這事闯袒』⒍兀” “怎么了游岳?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)其徙。 經(jīng)常有香客問我胚迫,道長(zhǎng),這世上最難降的妖魔是什么唾那? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任访锻,我火速辦了婚禮,結(jié)果婚禮上闹获,老公的妹妹穿的比我還像新娘期犬。我一直安慰自己,他們只是感情好避诽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布龟虎。 她就那樣靜靜地躺著,像睡著了一般沙庐。 火紅的嫁衣襯著肌膚如雪鲤妥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天拱雏,我揣著相機(jī)與錄音棉安,去河邊找鬼。 笑死铸抑,一個(gè)胖子當(dāng)著我的面吹牛贡耽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播羡滑,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼菇爪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了柒昏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤熙揍,失蹤者是張志新(化名)和其女友劉穎职祷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體届囚,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡有梆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了意系。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泥耀。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蛔添,靈堂內(nèi)的尸體忽然破棺而出痰催,到底是詐尸還是另有隱情兜辞,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布夸溶,位于F島的核電站逸吵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缝裁。R本人自食惡果不足惜扫皱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捷绑。 院中可真熱鬧韩脑,春花似錦、人聲如沸粹污。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厕怜。三九已至衩匣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粥航,已是汗流浹背琅捏。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留递雀,地道東北人柄延。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像缀程,于是被迫代替她去往敵國和親搜吧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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