Spring Cloud Zuul
服務網關是微服務架構中一個不可或缺的部分。通過服務網關統一向外系統提供REST API的過程中,除了具備服務路由、均衡負載功能之外,它還具備了權限控制等功能。
Spring Cloud Netflix中的Zuul就擔任了這樣的一個角色,為微服務架構提供了前門保護的作用,同時將權限控制這些較重的非業務邏輯內容遷移到服務路由層面,使得服務集群主體能夠具備更高的可復用性和可測試性。
在Spring Cloud體系中, Spring Cloud Zuul 封裝了Zuul組件,作為一個API網關,負責提供負載均衡、反向代理和權限認證。
Zuul工作機制
過濾器機制
Zuul的核心是一系列的filters, 其作用類似Servlet框架的Filter,Zuul把客戶端請求路由到業務處理邏輯的過程中,這些filter在路由的特定時期參與了一些過濾處理,比如實現鑒權、流量轉發、請求統計等功能。Zuul的整個運行機制,可以用下圖來描述。
過濾器的生命周期
Filter的生命周期有4個,分別是“PRE”、“ROUTING”、“POST”、“ERROR”,整個生命周期可以用下圖來表示。
基於Zuul的這些過濾器,可以實現各種豐富的功能,而這些過濾器類型則對應於請求的典型生命周期。
PRE: 這種過濾器在請求被路由之前調用。我們可利用這種過濾器實現身份驗證、在集群中選擇請求的微服務、記錄調試信息等。
ROUTING:這種過濾器將請求路由到微服務。這種過濾器用於構建發送給微服務的請求,並使用Apache HttpClient或Netfilx Ribbon請求微服務。
POST:這種過濾器在路由到微服務以后執行。這種過濾器可用來為響應添加標准的HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端等。
ERROR:在其他階段發生錯誤時執行該過濾器。
除了默認的過濾器類型,Zuul還允許我們創建自定義的過濾器類型。例如,我們可以定制一種STATIC類型的過濾器,直接在Zuul中生成響應,而不將請求轉發到后端的微服務。
Zuul中默認實現的Filter
Zuul默認實現了很多Filter,這些Filter如下面表格所示。
類型 | 順序 | 過濾器 | 功能 |
---|---|---|---|
pre | -3 | ServletDetectionFilter | 標記處理Servlet的類型 |
pre | -2 | Servlet30WrapperFilter | 包裝HttpServletRequest請求 |
pre | -1 | FormBodyWrapperFilter | 包裝請求體 |
route | 1 | DebugFilter | 標記調試標志 |
route | 5 | PreDecorationFilter | 處理請求上下文供后續使用 |
route | 10 | RibbonRoutingFilter | serviceId請求轉發 |
route | 100 | SimpleHostRoutingFilter | url請求轉發 |
route | 500 | SendForwardFilter | forward請求轉發 |
post | 0 | SendErrorFilter | 處理有錯誤的請求響應 |
post | 1000 | SendResponseFilter | 處理正常的請求響應 |
我們先看看Zuul的工作原理,Zuul是主要起路由轉發和路由攔截作用的,這里直接說Zuul和Feign集成的工作流程如下:
看看他的主程序:
再看看application.yml里的配置文件:
啟動我們的注冊中心服務、至少一個服務提供者、啟動Feign服務消費者、啟動我們的Zuul服務消費者,啟動正常:
打開瀏覽器器,輸入http://localhost:8768/service-feign/hello?name=111這是我們基於Feign的請求轉發
打開瀏覽器器,輸入http://localhost:8768/service-feign/hi?name=111這是我們基於RestTemplate的請求轉發
可以看到,我們成功將我們的路由請求轉發到Feign服務消費者模塊上了,接下來我們要實現以下Zuul對請求的攔截和熔斷處理,
攔截就是在轉發之前或者之后當請求到達Feign之前做攔截處理,這個是很重要的功能,熔斷是當我們路由轉發請求的服務不可用該怎么處理響應呢?
一、路由請求攔截
簡單看一下代碼知道這個過濾器繼承了ZuulFilter,在run()方法里日志輸出了請求的URL路徑和對參數是否有name做了簡單的攔截過濾,請求http://localhost:8768/service-feign/hello?
二、路由熔斷
注意這里的一段代碼
我們的熔斷路由器配置的是service-feign(就是我們zuul請求路由的這個這個服務),我們關閉這個服務,保留其他之前開啟的服務,請求http://localhost:8768/service-feign/hi?name=111
自此,我們可以
自此,說明我們自定義的熔斷器已經起作用了,這課的內容到此為止,下回再見!
===============================================================================