爲何須要API Gateway
一、簡化客戶端調用複雜度前端
在微服務架構模式下後端服務的實例數通常是動態的,對於客戶端而言很難發現動態改變的服務實例的訪問地址信息。所以在基於微服務的項目中爲了簡化前端的調用邏輯,一般會引入API Gateway做爲輕量級網關,同時API Gateway中也會實現相關的認證邏輯從而簡化內部服務之間相互調用的複雜度。java
二、數據裁剪以及聚合spring
一般而言不一樣的客戶端對於顯示時對於數據的需求是不一致的,好比手機端或者Web端又或者在低延遲的網絡環境或者高延遲的網絡環境。後端
所以爲了優化客戶端的使用體驗,API Gateway能夠對通用性的響應數據進行裁剪以適應不一樣客戶端的使用需求。同時還能夠將多個API調用邏輯進行聚合,從而減小客戶端的請求數,優化客戶端用戶體驗api
三、多渠道支持安全
固然咱們還能夠針對不一樣的渠道和客戶端提供不一樣的API Gateway,對於該模式的使用由另一個你們熟知的方式叫Backend for front-end, 在Backend for front-end模式當中,咱們能夠針對不一樣的客戶端分別建立其BFF。網絡
四、遺留系統的微服務化改造架構
對於系統而言進行微服務改造一般是因爲原有的系統存在或多或少的問題,好比技術債務,代碼質量,可維護性,可擴展性等等。API Gateway的模式一樣適用於這一類遺留系統的改造,經過微服務化的改造逐步實現對原有系統中的問題的修復,從而提高對於原有業務響應力的提高。經過引入抽象層,逐步使用新的實現替換舊的實現。app
在Spring Cloud體系中, Spring Cloud Zuul就是提供負載均衡、反向代理、權限認證的一個API gateway。負載均衡
Spring Cloud Zuul
Spring Cloud Zuul路由是微服務架構的不可或缺的一部分,提供動態路由,監控,彈性,安全等的邊緣服務。Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器。
下面咱們經過代碼來了解Zuul是如何工做的
簡單使用
一、添加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>
引入spring-cloud-starter-zuul
包
二、配置文件
spring.application.name=gateway-service-zuul server.port=8888 #這裏的配置表示,訪問/it/** 直接重定向到http://www.ityouknow.com/** zuul.routes.baidu.path=/it/** zuul.routes.baidu.url=http://www.ityouknow.com/
三、啓動類
@SpringBootApplication @EnableZuulProxy public class GatewayServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(GatewayServiceZuulApplication.class, args); } }
啓動類添加@EnableZuulProxy,支持網關路由。
史上最簡單的zuul案例就配置完了
服務化
經過url映射的方式來實現zull的轉發有侷限性,好比每增長一個服務就須要配置一條內容,另外後端的服務若是是動態來提供,就不能採用這種方案來配置了。實際上在實現微服務架構時,服務名與服務實例地址的關係在eureka server中已經存在了,因此只須要將Zuul註冊到eureka server上去發現其餘服務,就能夠實現對serviceId的映射。
咱們結合示例來講明,在上面示例項目gateway-service-zuul-simple的基礎上來改造。
一、添加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
增長spring-cloud-starter-eureka
包,添加對eureka的支持。
二、配置文件
配置修改成:
spring.application.name=gateway-service-zuul server.port=8888 zuul.routes.api-a.path=/producer/** zuul.routes.api-a.serviceId=spring-cloud-producer eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
三、測試
依次啓動 spring-cloud-eureka、 spring-cloud-producer、gateway-service-zuul-eureka,訪問:http://localhost:8888/producer/hello?name=%E5%B0%8F%E6%98%8E,返回:hello 小明,this is first messge
說明訪問gateway-service-zuul-eureka的請求自動轉發到了spring-cloud-producer,而且將結果返回。
爲了更好的模擬服務集羣,咱們複製spring-cloud-producer項目改成spring-cloud-producer-2,修改spring-cloud-producer-2項目端口爲9001,controller代碼修改以下:
@RestController public class HelloController { @RequestMapping("/hello") public String index(@RequestParam String name) { return "hello "+name+",this is two messge"; } }
修改完成後啓動spring-cloud-producer-2
,重啓gateway-service-zuul-eureka
。測試屢次訪問http://localhost:8888/producer/hello?name=%E5%B0%8F%E6%98%8E
,依次返回:
hello 小明,this is first messge hello 小明,this is two messge hello 小明,this is first messge hello 小明,this is two messge ...
說明經過zuul成功調用了producer服務而且作了均衡負載。
網關的默認路由規則
可是若是後端服務多達十幾個的時候,每個都這樣配置也挺麻煩的,spring cloud zuul已經幫咱們作了默認配置。默認狀況下,Zuul會代理全部註冊到Eureka Server的微服務,而且Zuul的路由規則以下:http://ZUUL_HOST:ZUUL_PORT/微服務在Eureka上的serviceId/**會被轉發到serviceId對應的微服務。
咱們註銷掉gateway-service-zuul-eureka項目中關於路由的配置:
#zuul.routes.api-a.path=/producer/** #zuul.routes.api-a.serviceId=spring-cloud-producer
從新啓動後,訪問http://localhost:8888/spring-cloud-producer/hello?name=%E5%B0%8F%E6%98%8E,測試返回結果和上述示例相同,說明Spring cloud zuul默認已經提供了轉發功能。
到此zuul的基本使用咱們就介紹完了。關於zuul更高級使用,咱們下篇再來介紹。
總體架構以下:
願意瞭解框架技術或者源碼的朋友直接求求交流分享技術:貳一四七七七五六叄叄