Spring Cloud Zuul源碼分析

Spring Cloud Zuul中介紹了Zuul 1.x的基本使用,本文從源碼角度介紹一下zuul的底層實現。

先來一張zuul的整體流程圖。

可以看到Zuul本質上是一個servlet,在這個servlet裏面封裝了一系列的過濾器,然後再進行請求的轉發或者結果的返回。所以下面我們的分析重點就是這個zuul filter。

和之前的源碼分析一樣,從入口註解@EnableZuulProxy開始。

ZuulProxyConfiguration類稍後再來看,先來看下它的父類ZuulConfiguration。

在ZuulConfiguration中註冊了前面說的重點--ZuulServlet。接着就詳細的看下這個類。

它繼承了HttpServlet,在其init方法中初始化了ZuulRunner。

我們知道servlet中的service方法會在請求到達時執行,ZuulServlet在這裏定義了zuul filter中不同方法的執行順序,pre->route->post,中間若有異常則執行error。隨便選一個filter方法進入。

他會調用先前在init方法中初始化的ZuulRunner中的相關方法,執行流程接着就來到ZuulRunner

獲取FilterProcessor實例,調用FilterProcessor中的對應方法

在runFilters方法中獲取所有該類型的過濾器(這裏是獲取所有“post”類型的過濾器)並根據filterOrder排序,返回一個過濾器鏈並依次執行processZuulFilter方法

調用runFilter中執行過濾邏輯

調用shouldFilter判斷是否執行過濾,若是再執行run方法自定義邏輯,封裝成ZuulFilterResult返回。其中上面提到的shouldFilter,filterOrder,run等方法都是我們自定義過濾器時需要實現的方法。到這裏,zuul的核心ZuulServlet就已經分析完了。

除了主要的ZuulFilter,還註冊了其他的一些Filter,挑選一個簡單的來看一下

上面的DebugFilter類型爲“pre”,如果開啓debug則執行該過濾器並在RequestContext中設置debug屬性。下面這個表格列出了ZuulConfiguration與ZuulProxyConfiguration註冊的所有過濾器。

我們在實現自己的Zuul過濾器時,可以參考上面過濾器的實現並設置合適的過濾器類型與order大小。

過濾器已經創建好了,那麼存儲在哪?

ZuulConfiguration中還包含了一個內部配置類,裏面註冊了ZuulFilterInitializer

ZuulFilterInitializer類是一個監聽器,將在servlet環境啓動時執行contextInitialized方法,將所有的過濾器放入FilterRegistry中。

因爲zuul支持動態的添加過濾器,所以需要有方法定時的去加載系統中的過濾器。

他會在FilterFileManager中開啓定時輪詢,掃描系統中的過濾器並加入到過濾器集合中。

回到子類ZuulProxyConfiguration,由於@EnableZuulProxy默認開啓了ribbon負載均衡,所以這裏主要導入了Ribbon需要的相關配置

到這裏分析基本已經結束了,上面的代碼基於zuul 1.x,在16年的時候zuul進行了升級,在zuul 2.x中,架構進行調整,整體採用Netty實現,調用方式由原來的阻塞調用變爲非阻塞調用,I/O模型變爲I/O複用模型(UNIX中的五種I/O模型),相比zuul 1有更高的吞吐量與併發量,裏面關於過濾器的部分發生了較大變化,具體見https://github.com/Netflix/zuul/wiki。然而Spring官方並不沒有集成zuul 2,因爲它們自己開發了一個網關Spring Cloud Gateway,gateway基於Netty與webflux實現,也是異步非阻塞的,如果使用Spring Cloud構建微服務的話,又希望網關有更好的性能,建議使用Spring Cloud Gateway作爲自己的網關組件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章