SpringCloud實戰八:Gateway之 Spring Cloud Zuul
1.Zuul相關概念
Zuul是netflix開源的一個API Gateway 閘道器, 本質上是一個web servlet應用,用來做統一認證與鑑權、動態路由、監控、彈性、安全等邊緣服務的框架,它的核心是做服務轉發。
2.為什麼需要閘道器
使用微服務架構後,大型系統往往會拆分為多個微服務,前端頁面可能有商品,評價,廣告、推薦模組等等,如果沒有閘道器,前端頁面就需要自己關心後端各個服務模組的地址,如果服務釋出多個節點,或者釋出地址變更後,前端頁面要對應改過來,這就會很複雜。有了閘道器後,前端只需要向閘道器發起請求,不需要關心服務是否釋出多份,服務地址是否變動,遮蔽後端的複雜性,它還能將多個API呼叫邏輯進行聚合,從而減少客戶端的請求數
3.Zuul的工作原理
Zuul的核心是一系列的filters,它能在進行 HTTP請求或者響應時執行相關操作,其作用可以類比Servlet框架的Filter,它主要有以下幾點特性:
- Filter型別:pre、post、route、error,型別決定filter在Filter鏈中的執行順序
- Filter執行順序:同一型別的Filter執行順序通過 filterOrder()方法設定
- Filter的執行條件:決定該filter是否執行,為true就會執行,為false就不執行
- Filter的run方法,執行filter 實際上就是執行run()方法中的程式碼
- Filter過濾鏈資料傳遞是通過RequestContext共享的,它內部是執行緒ThreadLocal實現
4. Zuul 與 Spring Cloud Zuul
- Zuul是Netflix 2012年3月開源的,最開始1.0版本,預設是Servlet開發的(同步阻塞模式),原生Zuul是支援動態過濾器的,因為閘道器釋出後,它承受大量流量,不能經常重啟,能支援動態新增過濾器就會很方便,動態過濾器是通過Groovy指令碼,也就是java程式碼,能動態編譯、執行。
- Zuul2.0版本是 Netfilx 2018-5月開源的,它把 Servlet換成了 Netty,事件處理器(handler)Netty Server接收請求,Netty Client響應(非同步非阻塞),至於對比1.x版本有效能的提升,netfilx官方和網友都有測試,同時支援WebSocket和其他特性
- Spring Cloud Zuul 是Pivotal 整合 Netfilx Zuul 到Spring Cloud 生態中,命名為Spring Cloud Zuul,它閹割了原生zuul的動態過濾器功能,整合與優化某些功能,如:使用註解就能啟用Zuul閘道器,大大提高了開發效率
5.Spring Cloud Zuul 實踐
為了高效的開發,下面使用Spring Cloud 整合的Zuul,非原生 Netfilx的Zuul,以下統稱 Zuul。
瞭解以上概念後進行程式碼實踐,思路:利用Zuul閘道器做服務轉發,有3個角色,eureka註冊中心,zuul閘道器,服務提供者,eureka與服務提供者專案請參考之前的部落格,都有程式碼實踐。
- 建立Spring Cloud Zuul專案,引用eureka-client與zuul:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
- 在啟動主類上啟用註冊中心與Zuul
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
- 配置檔案中配置註冊中心與路由規則:
server.port=9999
spring.application.name=zuul-service
eureka.instance.prefer-ip-address=true
#配置eureka-server security的賬戶資訊
eureka.client.serviceUrl.defaultZone=http://zy:[email protected]:10025/eureka/
#定義zuul的路由規則,請求的路徑是provider的,就轉發到provider-service
zuul.routes.provider-service.serviceId=provider-service
zuul.routes.provider-service.path=/provider/**
簡單的zuul閘道器就完成了
-
啟動eureka與服務提供者,看看註冊中心,已經有 ZUUL-SERVICE、PROVIDER-SERVICE服務了
-
服務提供者的程式碼很簡單,根據傳入的name引數,返回字串
@RequestMapping("/hello")
public String hello(String name){
return "hello " + name;
}
- 結合閘道器路由規則與服務進行訪問,地址為: http://localhost:9999/provider/hello?name=zhuyu
可以看到,請求已經正確轉發到 Provider-Service服務上了
閘道器的目的是轉發請求,加個認證與鑑權就好,不要寫太多業務邏輯,Zuul1.x版本是同步阻塞模式,會降低吞吐量
此示例只是簡單的介紹 Zuul 閘道器的轉發功能,生產環境請自行擴充套件一些高階功能,如限流、動態路由、灰度釋出等
程式碼已上傳至碼雲,原始碼,專案使用的版本資訊如下:
- SpringBoot 2.0.6.RELEASE
- SpringCloud Finchley.SR2