天天看點

SpringCloud(三) Zuul

有了eureka 、 feign 和 hystrix 後,基本上就搭建了簡易版的分布式項目,但仍存在一些問題,比如:

1、如果我們的微服務中有很多個獨立服務都要對外提供服務,那麼我們要如何去管理這些接口?特别是當項目非常龐大的情況下要如何管理?

2、在微服務中,一個獨立的系統被拆分成了很多個獨立的服務,為了確定安全,權限管理也是一個不可回避的問題,如果在每一個服務上都添加上相同的權限驗證代碼來確定系統不被非法通路,那麼工作量也就太大了,而且維護也非常不友善。

是以出現了網關,它就像一個安檢站一樣,所有外部的請求都需要經過它的排程與過濾,然後 API 網關來實作請求路由、負載均衡、權限驗證等功能。

建立spring boot工程并添加依賴:

在入口類上添加@EnableZuulProxy 注解,開啟 Zuul 的 API 網關服務功能:

在application.yml中添加路由規則

說明:以上配置的路由規則就是比對所有符合/api-zuul/**的請求,隻要路徑中帶有/api-zuul/都将被轉發到 springcloud-consumer 服務上。比如:localhost:8766/api-zuul/web/hello 轉發到 http://localhost:8764/web/hello

建構成功

SpringCloud(三) Zuul

定義一個過濾器類并繼承自 ZuulFilter,并将該 Filter 作為一個 Bean:

filterType 方法的傳回值為過濾器的類型,決定了過濾器在哪個生命周期執行,pre 表示在路由之前執行過濾器,其他值還有 post、error、route 和 static,當然也可以自定義。

filterOrder 方法表示過濾器的執行順序,當過濾器很多時,我們可以通過該方法的傳回值來指定過濾器的執行順序。

shouldFilter 方法用來判斷過濾器是否執行,true 表示執行,false 表示不執行。

run 方法則表示過濾的具體邏輯,如果請求位址中攜帶了 token 參數的話,則認為是合法請求,否則為非法請求,如果是非法請求的話,首先設定ctx.setSendZuulResponse(false),表示不對該請求進行路由,然後設定響應碼和響應值。這個 run 方法的傳回值目前暫時沒有任何意義,可以傳回任意值。

不攜帶token,localhost:8766/api-zuul/web/hello

SpringCloud(三) Zuul

攜帶token,localhost:8766/api-zuul/web/hello?token=213

SpringCloud(三) Zuul

在前面的例子中,

當通路位址符合 /api-zuul/ 規則的時候,會被自動定位到springcloud-consumer 服務上,有點麻煩,還可以簡化為:

zuul.routes 後面跟着的是服務名,服務名後面跟着的是路徑規則,這種配置方式更簡單。

預設情況下,Eureka 上所有注冊的服務都會被 Zuul 建立映射關系來進行路由。

但如果希望 springcloud-service-provider 作為服務提供者隻對服務消費者提供服務,不對外提供服務:

還可以進一步細化,比如不想給/hello 接口路由:

也可以統一的為路由規則增加字首:

路由規則通配符:

SpringCloud(三) Zuul

一般情況下 API 網關隻是作為各個微服務的統一入口,但是有時候我們可能也需要在 API 網關服務上做一些特殊的業務邏輯處理,那麼我們可以讓請求到達 API 網關後,再轉發給自己本身,由 API 網關自己來處理,那麼我們可以進行如下的操作:

在 application.yml 中:

首先看一下Zuul 請求的生命周期:

SpringCloud(三) Zuul

正常情況下所有的請求都是按照 pre、route、post 的順序來執行,然後由 post 傳回 response

在 pre 階段,如果有自定義的過濾器則執行自定義的過濾器

pre、routing、post 的任意一個階段如果抛異常了,則執行 error 過濾器

有兩種方式統一處理異常:

禁用 zuul 預設的異常處理 SendErrorFilter 過濾器,然後自定義我們自己的 Errorfilter 過濾器

在 AuthFiler 裡的run()方法添加異常 <code>int i = 10 / 0</code>

SpringCloud(三) Zuul

自定義全局 error 錯誤頁面

開啟 zuul 預設的異常處理 SendErrorFilter 過濾器,并注釋掉 ErrorFilter 類

SpringCloud(三) Zuul