微服務網關Zuul過濾器Filter

Zuul本質

Zuul是一個網關,關於網關的介紹參考:億級流量架構之網關設計思路、常見網關對比, 可知Zuul是一個業務網關, 而深刻了解Zuul, 基本就是一系列過濾器的集合:html

img

Zuul的過濾器

下面開始詳細瞭解Zuul的過濾器, 主要有pre、rout、post、error四種過濾器類型,將這個整明白了, zuul的使用就過大半了。java

四種類型過濾器調用順序:架構

過濾器類型定義在filterType方法中, 返回一個字符串表明過濾器的類型,在zuul中定義的四種不一樣生命週期的過濾器類型,主要功能以下:ide

  • 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能正常運做。微服務

每一種處理器具體細分多種, 參考圖(利用谷歌檢索難以搜到圖的來源, 這兒給出我參考博客的地址):post

須要記住幾個常見的, Route中有三種過濾器, 分別是:ui

RibbonXXXFilter : 路由到服務.net

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只在同一級別的過濾器中才會被考慮。

相關文章
相關標籤/搜索