1、Zuul過濾器生命周期
Zuul大部分功能都是通過過濾器來實現的,Zuul定義了4種標准的過濾器類型,這些過濾器類型對應於請求的典型生命周期。
a、pre: 這種過濾器在請求被路由之前調用。可利用這種過濾器實現身份驗證、在集群中選擇請求的微服務,記錄調試信息等。
b、routing: 這種過濾器將請求路由到微服務。這種過濾器用於構建發送給微服務的請求,並使用apache httpclient或netflix ribbon請求微服務。
c、post: 這種過濾器在路由到微服務以后執行。這種過濾器可用來為響應添加標准的http header、收集統計信息和指標、將響應從微服務發送給客戶端等。
e、error: 在其他階段發送錯誤時執行該過濾器。
除了默認的過濾器類型,zuul還允許創建自定義的過濾器類型。例如,可以定制一種static類型的過濾器,直接在zuul中生成響應,而不將請求轉發到后端的微服務。
zuul請求的生命周期如下圖,該圖詳細描述了各種類型的過濾器的執行順序。
2、核心過濾器
我們可以在源碼中查看和了解它們,它們定義在spring-cloud-netflix-core模塊的org.springframework.cloud.netflix.zuul.filters包下。
如上圖所示,在默認啟用的過濾器中包含了三種不同生命周期的過濾器,這些過濾器都非常重要,可以幫助我們理解Zuul對外部請求處理的過程,以及幫助我們如何在此基礎上擴展過濾器去完成自身系統需要的功能。
2、DebugFilter過濾器源碼講解
package org.springframework.cloud.netflix.zuul.filters.pre; import javax.servlet.http.HttpServletRequest; import com.netflix.config.DynamicBooleanProperty; import com.netflix.config.DynamicPropertyFactory; import com.netflix.config.DynamicStringProperty; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.constants.ZuulConstants; import com.netflix.zuul.context.RequestContext; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; public class DebugFilter extends ZuulFilter { private static final DynamicBooleanProperty ROUTING_DEBUG = DynamicPropertyFactory .getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false); private static final DynamicStringProperty DEBUG_PARAMETER = DynamicPropertyFactory .getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug"); @Override public String filterType() { return PRE_TYPE; } @Override public int filterOrder() { return DEBUG_FILTER_ORDER; } @Override public boolean shouldFilter() { HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); if ("true".equals(request.getParameter(DEBUG_PARAMETER.get()))) { return true; } return ROUTING_DEBUG.get(); } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.setDebugRouting(true); ctx.setDebugRequest(true); return null; } }
當請求參數中設置了debug參數時,該過濾器會將當前請求上下文中的RequestContext.setDebugRouting()和RequestContext.setDebugRequest()設置為true,這樣后續的過濾器可以根據這兩個參數信息定義一些debug信息,當生產環境出現問題時,我們就可以通過增加該參數讓后台打印出debug信息,以幫助我們進行問題分析。對於請求中的debug參數的名稱,我們可以通過zuul.debug.parameter進行自定義。
要想實現Filter,通過繼承ZuulFilter然后重寫上面的4個方法,就可以實現一個簡單的過濾器,下面就相關注意點進行說明
filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下:
pre:可以在請求被路由之前調用
route:在路由請求時候被調用
post:在route和error過濾器之后被調用
error:處理請求時發生錯誤時被調用
filterOrder:通過int值來定義過濾器的執行順序
shouldFilter:返回一個boolean類型來判斷該過濾器是否要執行,所以通過此函數可實現過濾器的開關。在上例中,我們直接返回true,所以該過濾器總是生效
run:過濾器的具體邏輯。在該函數中,我們可以實現自定義的過濾邏輯,來確定是否要攔截當前的請求,不對其進行后續的路由,或是在請求路由返回結果之后,對處理結果做一些加工等。