為什麼需要API Gateway
1、簡化客戶端呼叫複雜度
在微服務架構模式下後端服務的例項數一般是動態的,對於客戶端而言很難發現動態改變的服務例項的訪問地址資訊。因此在基於微服務的專案中為了簡化前端的呼叫邏輯,通常會引入API Gateway作為輕量級閘道器,同時API Gateway中也會實現相關的認證邏輯從而簡化內部服務之間相互呼叫的複雜度。
2、資料裁剪以及聚合
通常而言不同的客戶端對於顯示時對於資料的需求是不一致的,比如手機端或者Web端又或者在低延遲的網路環境或者高延遲的網路環境。
因此為了優化客戶端的使用體驗,API Gateway可以對通用性的響應資料進行裁剪以適應不同客戶端的使用需求。同時還可以將多個API呼叫邏輯進行聚合,從而減少客戶端的請求數,優化客戶端使用者體驗
3、多渠道支援
當然我們還可以針對不同的渠道和客戶端提供不同的API Gateway,對於該模式的使用由另外一個大家熟知的方式叫Backend for front-end, 在Backend for front-end模式當中,我們可以針對不同的客戶端分別建立其BFF
4、遺留系統的微服務化改造
對於系統而言進行微服務改造通常是由於原有的系統存在或多或少的問題,比如技術債務,程式碼質量,可維護性,可擴充套件性等等。API Gateway的模式同樣適用於這一類遺留系統的改造,通過微服務化的改造逐步實現對原有系統中的問題的修復,從而提升對於原有業務響應力的提升。通過引入抽象層,逐步使用新的實現替換舊的實現。
在Spring Cloud體系中, Spring Cloud Zuul就是提供負載均衡、反向代理、許可權認證的一個API gateway。
Spring Cloud Zuul
Spring Cloud Zuul路由是微服務架構的不可或缺的一部分,提供動態路由,監控,彈性,安全等的邊緣服務。Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器。
下面我們通過程式碼來了解Zuul是如何工作的
簡單使用
1、新增依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>複製程式碼
引入spring-cloud-starter-zuul
包
2、配置檔案
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/複製程式碼
3、啟動類
@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
的基礎上來改造。
1、新增依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>複製程式碼
增加spring-cloud-starter-eureka
包,新增對eureka的支援。
2、配置檔案
配置修改為:
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/複製程式碼
3、測試
依次啟動 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更高階使用,我們下篇再來介紹。
Spring Cloud大型企業分散式微服務雲構建的B2B2C電子商務平臺原始碼請加企鵝求求:一零三八七七四六二六