Zuul API網(wǎng)關(guān)

core:Java功能增強 ——過濾器

微服務(wù)中引入API網(wǎng)關(guān)服務(wù)的必要性:
1、首先微服務(wù)架構(gòu)中服務(wù)單獨細化并存在多個實例,那就有必要維護服務(wù)實例列表和路由規(guī)則等等,系統(tǒng)越大越復(fù)雜越難維護(當然服務(wù)實例列表可以從Eureka中獲取)。那如果用網(wǎng)關(guān)來實現(xiàn)請求路由與負載均衡呢?
2、服務(wù)中經(jīng)常會有一些權(quán)限校驗機制等,而且每個服務(wù)都要有。最原始的就是在每個服務(wù)中都寫校驗代碼,改進一點就是把校驗機制做成一個單獨的服務(wù),但即使是這樣,每個服務(wù)都需要自己去調(diào)用一下校驗服務(wù)。如果使用在網(wǎng)關(guān)中寫校驗機制,由它統(tǒng)一過濾呢?

過濾機制

Zuul最重要的應(yīng)該屬于它的過濾機制,zuul使用的不是web容器的Filter,是自己實現(xiàn)的Filter,具體如下:
先定義一個servlet:
service方法如下:

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    try {
        this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse);
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();

        try {
            this.preRoute();             ******************
        } catch (ZuulException var13) {
            this.error(var13);
            this.postRoute();
            return;
        }

        try {
            this.route();                      ******************
        } catch (ZuulException var12) {
            this.error(var12);
            this.postRoute();
            return;
        }

        try {
            this.postRoute();                  ******************
        } catch (ZuulException var11) {
            this.error(var11);
        }
    } catch (Throwable var14) {
        this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName()));
    } finally {
        RequestContext.getCurrentContext().unset();
    }
}

void postRoute() throws ZuulException {
    this.zuulRunner.postRoute();
}

void route() throws ZuulException {
    this.zuulRunner.route();
}

void preRoute() throws ZuulException {
    this.zuulRunner.preRoute();
}

再使用定義的Runner來執(zhí)行自己的Filter:

 public void preRoute() throws ZuulException {
    try {
        this.runFilters("pre");
    } catch (ZuulException var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new ZuulException(var3, 500, "UNCAUGHT_EXCEPTION_IN_PRE_FILTER_" + var3.getClass().getName());
    }
}

而所有的Filter是放在一個List里的,過濾出對應(yīng)的Filter執(zhí)行:

  public Object runFilters(String sType) throws Throwable {
    if (RequestContext.getCurrentContext().debugRouting()) {
        Debug.addRoutingDebug("Invoking {" + sType + "} type filters");
    }

    boolean bResult = false;
    List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType);
    if (list != null) {
        for(int i = 0; i < list.size(); ++i) {
            ZuulFilter zuulFilter = (ZuulFilter)list.get(i);
            Object result = this.processZuulFilter(zuulFilter);
            if (result != null && result instanceof Boolean) {
                bResult |= (Boolean)result;
            }
        }
    }

    return bResult;
}

在processZuulFilter函數(shù)中會執(zhí)行filter.runFilter()。

thinking:Javaweb應(yīng)用中請求都是由servlet進行處理的,Spring中servlet會將請求轉(zhuǎn)發(fā)到對應(yīng)的controller。而Filter是在請求被Servlet處理之前攔截請求進行過濾的。在Zuul中這個Filter實現(xiàn)是定義了一個Servlet,在Servlet中調(diào)用自己的過濾器,通過過濾的請求會接著走后面的流程。
小問題:如果是SpringBoot項目,默認有一個DispatcherServlet,如果再定義一個自己的Servlet,那這兩個Servlet是怎么執(zhí)行的,是先執(zhí)行我們自己定義的?然后再走DispatcherServlet?
答:試了一下,當存在多個Servlet時,只會執(zhí)行url最精確的Servlet,比如MyServlet的url是“/hello”,那DispatcherServlet就不會執(zhí)行了(默認是“/”)。
(在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通過 @WebServlet、@WebFilter、@WebListener 注解自動注冊)

那問題來了。如果只會執(zhí)行一個Servlet,那么框架自定義的Servlet處理后,請求要怎么轉(zhuǎn)給DispatcherServlet再轉(zhuǎn)給Controlller呢?
答:這里是網(wǎng)關(guān),沒有Controller啊,當然DispatcherServlet也會執(zhí)行,很奇怪,但是好像它執(zhí)不執(zhí)行沒有影響?應(yīng)該是有個操作向server轉(zhuǎn)發(fā)請求(過濾通過后),那這個操作在哪呢?
zuul有三大類過濾器,分別是pre、route、post。對應(yīng)著請求前,請求中和請求后。所以向服務(wù)實例轉(zhuǎn)發(fā)請求應(yīng)該是在route過濾器中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容