摘要:該過濾器會判斷當前請求上下文中是否存在forward.to和serviceId參數,如果都不存在,那麼它就會執行具體過濾器的操作(如果有一個存在的話,說明當前請求已經被處理過了,因爲這兩個信息就是根據當前請求的路由信息加載進來的)。該過濾器只對請求上下文中存在forward.to參數的請求進行處理,即用來處理路由規則中的forward本地跳轉配置。

Zuul 過濾器

zuul 有四種過濾器類型,分別是:

1、Pre:過濾器在請求被路由之前調用。我們可利用這種過濾器實現身份驗證、在集羣中選擇請求的微服務、記錄調試信息等;

2、Routing:過濾器將請求路由到微服務。這種過濾器用於構建發送給微服務的請求,並使用Apache HttpClient或Netfilx Ribbon請求微服;

3、Post:過濾器在路由到微服務以後執行。這種過濾器可用來爲響應添加標準的HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端;

4、Error:在其他階段發生錯誤時執行該過濾器。除了默認的過濾器類型微服務;

zuul 過濾器的執行順序及生命週期( 先執行pre>routing>post 然後再在同類型的過濾器按照order大小執行,越小的越先被執行 ),如圖:

Pre過濾器:

1、ServletDetectionFilter:是最先被執行的過濾器。主要用來檢測當前請求是通過Spring的DispatcherServlet處理運行,還是通過ZuulServlet來處理運行的。

2、Servlet30WrapperFilter:是第二個執行的過濾器,會對所有請求生效。主要用來將原始的HttpServletRequest包裝成Servlet30RequestWrapper對象;

3、FormBodyWrapperFilter:該過濾器僅對兩種類請求生效,第一類是Content-Type爲application/x-www-form-urlencoded的請求,第二類是Content-Type爲multipart/form-data並且是由Spring的DispatcherServlet處理的請求。主要用來將符合要求的請求體包裝成FormBodyRequestWrapper對象;

4、PreDecorationFilter:是pre階段最後被執行的過濾器。該過濾器會判斷當前請求上下文中是否存在forward.to和serviceId參數,如果都不存在,那麼它就會執行具體過濾器的操作(如果有一個存在的話,說明當前請求已經被處理過了,因爲這兩個信息就是根據當前請求的路由信息加載進來的)。主要用來爲當前請求做一些預處理,比如:進行路由規則的匹配、在請求上下文中設置該請求的基本信息以及將路由匹配結果等一些設置信息等,這些信息將是後續過濾器進行處理的重要依據,我們可以通RequestContext.getCurrentContext()來訪問這些信息。

Routing過濾器:

1、RibbonRoutingFilter:是route階段第一個執行的過濾器。該過濾器只對請求上下文中存在serviceId參數的請求進行處理,即只對通過serviceId配置路由規則的請求生效。而該過濾器的執行邏輯就是面向服務路由的核心,它通過使用Ribbon和Hystrix來向服務實例發起請求,並將服務實例的請求結果返回;

2、SimpleHostRoutingFilter:是route階段第二個執行的過濾器。該過濾器只對請求上下文中存在routeHost參數的請求進行處理,即只對通過url配置路由規則的請求生效。而該過濾器的執行邏輯就是直接向routeHost參數的物理地址發起請求,該請求是直接通過httpclient包實現的,而沒有使用Hystrix命令進行包裝,所以這類請求並沒有線程隔離和斷路器的保護;

3、SendForwardFilter:是route階段第三個執行的過濾器。該過濾器只對請求上下文中存在forward.to參數的請求進行處理,即用來處理路由規則中的forward本地跳轉配置;

Post過濾器:

1、SendResponseFilter:是post階段最後執行的過濾器。該過濾器會檢查請求上下文中是否包含請求響應相關的頭信息、響應數據流或是響應體,只有在包含它們其中一個的時候就會執行處理邏輯。而該過濾器的處理邏輯就是利用請求上下文的響應信息來組織需要發送回客戶端的響應內容;

Error過濾器:

1、SendErrorFilter:該過濾器僅在請求上下文中包含error.status_code參數(由之前執行的過濾器設置的錯誤編碼)並且還沒有被該過濾器處理過的時候執行。而該過濾器的具體邏輯就是利用請求上下文中的錯誤信息來組織成一個forward到API網關/error錯誤端點的請求來產生錯誤響應;

如何自定義過濾器

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class CustomFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        System.out.println("通過自定義的路由器.......");
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        return null;
    }
}

備註: ctx 在往前臺返回內容時中文會出現亂碼, ctx.getResponse().setContentType("text/html;charset=UTF-8");

如何禁用過濾器

zuul.CustomFilter.pre.disable = true
相關文章