Zuul本質
Zuul是一個網關,關於網關的介紹參考:億級流量架構之網關設計思路、常見網關對比, 可知Zuul是一個業務網關, 而深入了解Zuul, 基本就是一系列過濾器的集合:
Zuul的過濾器
下面開始詳細了解Zuul的過濾器, 主要有pre、rout、post、error四種過濾器類型,將這個整明白了, zuul的使用就過大半了。
四種類型過濾器調用順序:
過濾器類型定義在filterType方法中, 返回一個字符串代表過濾器的類型,在zuul中定義的四種不同生命周期的過濾器類型,主要功能如下:
pre
:在請求被路由之前調用, 利用這種路由器進行鑒權等服務, 記錄日志、 限流route
:在路由請求時候被調用,作用是將請求路由到指定服務中去, 用於構建發送給微服務的請求, 並且用Http Client(或者Ribbon)請求微服務post
:在route和error過濾器之后被調用,可以用來添加Header , 記錄日志, 將響應返回給客戶端。error
:處理請求時發生錯誤時調用
從pre和route階段拋出的異常將會進入error階段,再進入到post階段進行返回。由於SendErrorFilter需要判斷請求上下文中是否包含
error.status_code
屬性:有的話就用SendErrorFilter處理錯誤結果;沒有的話就用SendResponseFilter返回正常結果,但是error.status_code
屬性默認是在各個階段過濾器中自己put進去的,這就導致,各個階段過濾器拋出異常之后,是沒有辦法返回錯誤結果的。因此,我們擴展了一個ErrorFilter來捕獲異常,然后手工的設置error.status_code
屬性,讓SendErrorFilter能正常運作。
每一種處理器具體細分多種, 參考圖(利用谷歌檢索難以搜到圖的來源, 這兒給出我參考博客的地址):
需要記住幾個常見的, Route中有三種過濾器, 分別是:
RibbonXXXFilter : 路由到服務
SimpleHostRoutingFilter : 路由到URL地址
SendForwardFilter : 轉向Filter自己
Filter流程以及參數解釋
創建過濾器, 一般是先繼承ZuulFilter然后重寫里面的方法,分別是:
filterType : 指定過濾器的類型, 分別是上文提到的四種,pre route post error
**filterOrder **: 指定過濾器執行順序, 數字越小越先執行
shouldFilter : 是否執行這個過濾器, 也就是上來就看這兒是true還是false, false的話就不執行這個過濾器的邏輯。
**run **: 過濾器執行的邏輯, 這一般是過濾器的重點內容。
下面示例一個限流過濾器:
@Component // 交給Spring管理
public class LimitFilter extends ZuulFilter {
@Override //指定類型為pre
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override // 執行執行等級
public int filterOrder() {
return -10;
}
@Override // 是否執行
public boolean shouldFilter() {
return true;
}
//創建令牌
private static final RateLimiter RATE_LIMITER = RateLimiter.create(5);
@Override
public Object run() throws ZuulException {
//拿到請求上下文
RequestContext currentContext = RequestContext.getCurrentContext();
if (RATE_LIMITER.tryAcquire()){
System.out.println("通過");
return null;
}else {
System.out.println("被限流了");
currentContext.setSendZuulResponse(false);
currentContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
需要注意的是, 之前說過pre執行順序比post高, 也就意味着即使post執行等級比pre的小的話, pre過濾器還是會優先執行, filterOrder
只在同一級別的過濾器中才會被考慮。