偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring Cloud源碼分析(四)Zuul:核心過(guò)濾器

開(kāi)發(fā) 開(kāi)發(fā)工具
通過(guò)前文的介紹,可以說(shuō)過(guò)濾器是Zuul實(shí)現(xiàn)API網(wǎng)關(guān)功能最為核心的部件,下面,我們就通過(guò)本文來(lái)詳細(xì)了解一下Spring Cloud Zuul的過(guò)濾器!

通過(guò)前文的介紹,我們對(duì)于Zuul的***印象通常是這樣的:它包含了對(duì)請(qǐng)求的路由和過(guò)濾兩個(gè)功能,其中路由功能負(fù)責(zé)將外部請(qǐng)求轉(zhuǎn)發(fā)到具體的微服務(wù)實(shí)例上,是實(shí)現(xiàn)外部訪問(wèn)統(tǒng)一入口的基礎(chǔ);而過(guò)濾器功能則負(fù)責(zé)對(duì)請(qǐng)求的處理過(guò)程進(jìn)行干預(yù),是實(shí)現(xiàn)請(qǐng)求校驗(yàn)、服務(wù)聚合等功能的基礎(chǔ)。然而實(shí)際上,路由功能在真正運(yùn)行時(shí),它的路由映射和請(qǐng)求轉(zhuǎn)發(fā)都是由幾個(gè)不同的過(guò)濾器完成的。其中,路由映射主要通過(guò)pre類型的過(guò)濾器完成,它將請(qǐng)求路徑與配置的路由規(guī)則進(jìn)行匹配,以找到需要轉(zhuǎn)發(fā)的目標(biāo)地址;而請(qǐng)求轉(zhuǎn)發(fā)的部分則是由route類型的過(guò)濾器來(lái)完成,對(duì)pre類型過(guò)濾器獲得的路由地址進(jìn)行轉(zhuǎn)發(fā)。所以,過(guò)濾器可以說(shuō)是Zuul實(shí)現(xiàn)API網(wǎng)關(guān)功能最為核心的部件,每一個(gè)進(jìn)入Zuul的HTTP請(qǐng)求都會(huì)經(jīng)過(guò)一系列的過(guò)濾器處理鏈得到請(qǐng)求響應(yīng)并返回給客戶端。

下面,我們就通過(guò)本文來(lái)詳細(xì)了解一下Spring Cloud Zuul的過(guò)濾器!以下內(nèi)容節(jié)選自《Spring Cloud微服務(wù)實(shí)戰(zhàn)》,稍做加工。

一、過(guò)濾器

在Spring Cloud Zuul中實(shí)現(xiàn)的過(guò)濾器必須包含4個(gè)基本特征:過(guò)濾類型、執(zhí)行順序、執(zhí)行條件、具體操作。這些元素看著似乎非常的熟悉,實(shí)際上它就是ZuulFilter接口中定義的四個(gè)抽象方法:

  1. String filterType(); 
  2.  
  3. int filterOrder(); 
  4.  
  5. boolean shouldFilter(); 
  6.  
  7. Object run(); 

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

filterType:該函數(shù)需要返回一個(gè)字符串來(lái)代表過(guò)濾器的類型,而這個(gè)類型就是在HTTP請(qǐng)求過(guò)程中定義的各個(gè)階段。在Zuul中默認(rèn)定義了四種不同生命周期的過(guò)濾器類型,具體如下:

  • pre:可以在請(qǐng)求被路由之前調(diào)用。
  • routing:在路由請(qǐng)求時(shí)候被調(diào)用。
  • post:在routing和error過(guò)濾器之后被調(diào)用。
  • error:處理請(qǐng)求時(shí)發(fā)生錯(cuò)誤時(shí)被調(diào)用。

filterOrder:通過(guò)int值來(lái)定義過(guò)濾器的執(zhí)行順序,數(shù)值越小優(yōu)先級(jí)越高。

shouldFilter:返回一個(gè)boolean類型來(lái)判斷該過(guò)濾器是否要執(zhí)行。我們可以通過(guò)此方法來(lái)指定過(guò)濾器的有效范圍。

run:過(guò)濾器的具體邏輯。在該函數(shù)中,我們可以實(shí)現(xiàn)自定義的過(guò)濾邏輯,來(lái)確定是否要攔截當(dāng)前的請(qǐng)求,不對(duì)其進(jìn)行后續(xù)的路由,或是在請(qǐng)求路由返回結(jié)果之后,對(duì)處理結(jié)果做一些加工等。

二、請(qǐng)求生命周期

上一節(jié)中,對(duì)于Spring Cloud Zuul中的過(guò)濾器類型filterType,我們已經(jīng)做過(guò)一些簡(jiǎn)單的介紹,Zuul默認(rèn)定義了四個(gè)不同的過(guò)濾器類型,它們覆蓋了一個(gè)外部HTTP請(qǐng)求到達(dá)API網(wǎng)關(guān),直到返回請(qǐng)求結(jié)果的全部生命周期。下圖源自Zuul的官方WIKI中關(guān)于請(qǐng)求生命周期的圖解,它描述了一個(gè)HTTP請(qǐng)求到達(dá)API網(wǎng)關(guān)之后,如何在各個(gè)不同類型的過(guò)濾器之間流轉(zhuǎn)的詳細(xì)過(guò)程。

WIKI中關(guān)于請(qǐng)求生命周期的圖解

從上圖中,我們可以看到,當(dāng)外部HTTP請(qǐng)求到達(dá)API網(wǎng)關(guān)服務(wù)的時(shí)候,首先它會(huì)進(jìn)入***個(gè)階段pre,在這里它會(huì)被pre類型的過(guò)濾器進(jìn)行處理,該類型的過(guò)濾器主要目的是在進(jìn)行請(qǐng)求路由之前做一些前置加工,比如請(qǐng)求的校驗(yàn)等。在完成了pre類型的過(guò)濾器處理之后,請(qǐng)求進(jìn)入第二個(gè)階段routing,也就是之前說(shuō)的路由請(qǐng)求轉(zhuǎn)發(fā)階段,請(qǐng)求將會(huì)被routing類型過(guò)濾器處理,這里的具體處理內(nèi)容就是將外部請(qǐng)求轉(zhuǎn)發(fā)到具體服務(wù)實(shí)例上去的過(guò)程,當(dāng)服務(wù)實(shí)例將請(qǐng)求結(jié)果都返回之后,routing階段完成,請(qǐng)求進(jìn)入第三個(gè)階段post,此時(shí)請(qǐng)求將會(huì)被post類型的過(guò)濾器進(jìn)行處理,這些過(guò)濾器在處理的時(shí)候不僅可以獲取到請(qǐng)求信息,還能獲取到服務(wù)實(shí)例的返回信息,所以在post類型的過(guò)濾器中,我們可以對(duì)處理結(jié)果進(jìn)行一些加工或轉(zhuǎn)換等內(nèi)容。另外,還有一個(gè)特殊的階段error,該階段只有在上述三個(gè)階段中發(fā)生異常的時(shí)候才會(huì)觸發(fā),但是它的***流向還是post類型的過(guò)濾器,因?yàn)樗枰ㄟ^(guò)post過(guò)濾器將最終結(jié)果返回給請(qǐng)求客戶端(實(shí)際實(shí)現(xiàn)上還有一些差別,后續(xù)介紹)。

三、核心過(guò)濾器

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

在默認(rèn)啟用的過(guò)濾器中包含了三種不同生命周期的過(guò)濾器

如上圖所示,在默認(rèn)啟用的過(guò)濾器中包含了三種不同生命周期的過(guò)濾器,這些過(guò)濾器都非常重要,可以幫助我們理解Zuul對(duì)外部請(qǐng)求處理的過(guò)程,以及幫助我們?nèi)绾卧诖嘶A(chǔ)上擴(kuò)展過(guò)濾器去完成自身系統(tǒng)需要的功能。下面,我們將逐個(gè)地對(duì)這些過(guò)濾器做一些詳細(xì)的介紹:

1. pre過(guò)濾器

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

  • Servlet30WrapperFilter:它的執(zhí)行順序?yàn)?2,是第二個(gè)執(zhí)行的過(guò)濾器。目前的實(shí)現(xiàn)會(huì)對(duì)所有請(qǐng)求生效,主要為了將原始的HttpServletRequest包裝成Servlet30RequestWrapper對(duì)象。
  • FormBodyWrapperFilter:它的執(zhí)行順序?yàn)?1,是第三個(gè)執(zhí)行的過(guò)濾器。該過(guò)濾器僅對(duì)兩種類請(qǐng)求生效,***類是Content-Type為application/x-www-form-urlencoded的請(qǐng)求,第二類是Content-Type為multipart/form-data并且是由Spring的DispatcherServlet處理的請(qǐng)求(用到了ServletDetectionFilter的處理結(jié)果)。而該過(guò)濾器的主要目的是將符合要求的請(qǐng)求體包裝成FormBodyRequestWrapper對(duì)象。
  • DebugFilter:它的執(zhí)行順序?yàn)?,是第四個(gè)執(zhí)行的過(guò)濾器。該過(guò)濾器會(huì)根據(jù)配置參數(shù)zuul.debug.request和請(qǐng)求中的debug參數(shù)來(lái)決定是否執(zhí)行過(guò)濾器中的操作。而它的具體操作內(nèi)容則是將當(dāng)前的請(qǐng)求上下文中的debugRouting和debugRequest參數(shù)設(shè)置為true。由于在同一個(gè)請(qǐng)求的不同生命周期中,都可以訪問(wèn)到這兩個(gè)值,所以我們?cè)诤罄m(xù)的各個(gè)過(guò)濾器中可以利用這兩值來(lái)定義一些debug信息,這樣當(dāng)線上環(huán)境出現(xiàn)問(wèn)題的時(shí)候,可以通過(guò)請(qǐng)求參數(shù)的方式來(lái)激活這些debug信息以幫助分析問(wèn)題。另外,對(duì)于請(qǐng)求參數(shù)中的debug參數(shù),我們也可以通過(guò)zuul.debug.parameter來(lái)進(jìn)行自定義。
  • PreDecorationFilter:它的執(zhí)行順序?yàn)?,是pre階段***被執(zhí)行的過(guò)濾器。該過(guò)濾器會(huì)判斷當(dāng)前請(qǐng)求上下文中是否存在forward.to和serviceId參數(shù),如果都不存在,那么它就會(huì)執(zhí)行具體過(guò)濾器的操作(如果有一個(gè)存在的話,說(shuō)明當(dāng)前請(qǐng)求已經(jīng)被處理過(guò)了,因?yàn)檫@兩個(gè)信息就是根據(jù)當(dāng)前請(qǐng)求的路由信息加載進(jìn)來(lái)的)。而它的具體操作內(nèi)容就是為當(dāng)前請(qǐng)求做一些預(yù)處理,比如:進(jìn)行路由規(guī)則的匹配、在請(qǐng)求上下文中設(shè)置該請(qǐng)求的基本信息以及將路由匹配結(jié)果等一些設(shè)置信息等,這些信息將是后續(xù)過(guò)濾器進(jìn)行處理的重要依據(jù),我們可以通過(guò)RequestContext.getCurrentContext()來(lái)訪問(wèn)這些信息。另外,我們還可以在該實(shí)現(xiàn)中找到一些對(duì)HTTP頭請(qǐng)求進(jìn)行處理的邏輯,其中包含了一些耳熟能詳?shù)念^域,比如:X-Forwarded-Host、X-Forwarded-Port。另外,對(duì)于這些頭域的記錄是通過(guò)zuul.addProxyHeaders參數(shù)進(jìn)行控制的,而這個(gè)參數(shù)默認(rèn)值為true,所以Zuul在請(qǐng)求跳轉(zhuǎn)時(shí)默認(rèn)地會(huì)為請(qǐng)求增加X(jué)-Forwarded-*頭域,包括:X-Forwarded-Host、X-Forwarded-Port、X-Forwarded-For、X-Forwarded-Prefix、X-Forwarded-Proto。我們也可以通過(guò)設(shè)置zuul.addProxyHeaders=false關(guān)閉對(duì)這些頭域的添加動(dòng)作。

《Spring Cloud實(shí)戰(zhàn)小貼士:Zuul處理Cookie和重定向》 一文中提到的加載敏感頭信息加入到忽略頭信息的操作調(diào)用就在PreDecorationFilter過(guò)濾器中實(shí)現(xiàn)。

2. route過(guò)濾器

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

3. post過(guò)濾器

  • SendErrorFilter:它的執(zhí)行順序?yàn)?,是post階段***個(gè)執(zhí)行的過(guò)濾器。該過(guò)濾器僅在請(qǐng)求上下文中包含error.status_code參數(shù)(由之前執(zhí)行的過(guò)濾器設(shè)置的錯(cuò)誤編碼)并且還沒(méi)有被該過(guò)濾器處理過(guò)的時(shí)候執(zhí)行。而該過(guò)濾器的具體邏輯就是利用請(qǐng)求上下文中的錯(cuò)誤信息來(lái)組織成一個(gè)forward到API網(wǎng)關(guān)/error錯(cuò)誤端點(diǎn)的請(qǐng)求來(lái)產(chǎn)生錯(cuò)誤響應(yīng)。
  • SendResponseFilter:它的執(zhí)行順序?yàn)?000,是post階段***執(zhí)行的過(guò)濾器。該過(guò)濾器會(huì)檢查請(qǐng)求上下文中是否包含請(qǐng)求響應(yīng)相關(guān)的頭信息、響應(yīng)數(shù)據(jù)流或是響應(yīng)體,只有在包含它們其中一個(gè)的時(shí)候就會(huì)執(zhí)行處理邏輯。而該過(guò)濾器的處理邏輯就是利用請(qǐng)求上下文的響應(yīng)信息來(lái)組織需要發(fā)送回客戶端的響應(yīng)內(nèi)容。

這里不列出具體代碼了,讀者可自行根據(jù)類名來(lái)查看源碼了解詳細(xì)處理過(guò)程。下圖是對(duì)上述過(guò)濾器根據(jù)順序、名稱、功能、類型做了綜合的整理,可以幫助我們?cè)谧远x過(guò)濾器或是擴(kuò)展過(guò)濾器的時(shí)候用來(lái)參考并全面地考慮整個(gè)請(qǐng)求生命周期的處理過(guò)程。

自定義過(guò)濾器或是擴(kuò)展過(guò)濾器

【本文為51CTO專欄作者“翟永超”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)51CTO聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2017-04-12 14:43:01

Spring ClouZuul過(guò)濾器

2023-01-26 01:41:27

核心全局過(guò)濾器

2022-05-13 08:23:07

Zuul微服務(wù)Zuul過(guò)濾器

2023-04-14 09:01:25

2021-01-14 08:13:39

Spring Clou應(yīng)用內(nèi)置過(guò)濾器

2009-09-29 13:55:23

Hibernate設(shè)置

2023-07-24 08:00:56

客戶端訪問(wèn)指定

2017-09-15 23:29:53

Spring Clou微服務(wù)架構(gòu)過(guò)濾器

2024-04-03 08:08:15

謂詞網(wǎng)關(guān)開(kāi)發(fā)

2021-07-05 15:22:03

Servlet過(guò)濾器客戶端

2024-01-05 09:04:35

隆過(guò)濾器數(shù)據(jù)結(jié)構(gòu)哈希函數(shù)

2024-11-04 08:45:48

布隆過(guò)濾器元數(shù)據(jù)指紋值

2009-07-08 15:30:56

Servlet過(guò)濾器

2009-07-14 09:09:08

Swing模型過(guò)濾器

2009-07-08 16:07:04

Servlet過(guò)濾器配

2011-06-29 16:14:59

Qt 事件 過(guò)濾器

2022-02-16 23:58:41

Spring過(guò)濾器驗(yàn)證碼

2023-02-15 08:12:19

http超時(shí)過(guò)濾器

2022-02-21 23:58:49

Spring過(guò)濾器順序值

2025-04-21 00:50:50

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)