springcloud(十):服務網關zuul


前面的文章我們介紹了,Eureka用於服務的注冊於發現,Feign支持服務的調用以及均衡負載,Hystrix處理服務的熔斷防止故障擴散,Spring Cloud Config服務集群配置中心,似乎一個微服務框架已經完成了。

我們還是少考慮了一個問題,外部的應用如何來訪問內部各種各樣的微服務呢?在微服務架構中,后端服務往往不直接開放給調用端,而是通過一個API網關根據請求的url,路由到相應的服務。當添加API網關后,在第三方調用端和服務提供方之間就創建了一面牆,這面牆直接與調用方通信進行權限控制,后將請求均衡分發給后台服務端。


## 為什么需要API Gateway

1、簡化客戶端調用復雜度

在微服務架構模式下后端服務的實例數一般是動態的,對於客戶端而言很難發現動態改變的服務實例的訪問地址信息。因此在基於微服務的項目中為了簡化前端的調用邏輯,通常會引入API Gateway作為輕量級網關,同時API Gateway中也會實現相關的認證邏輯從而簡化內部服務之間相互調用的復雜度。

2、數據裁剪以及聚合

通常而言不同的客戶端對於顯示時對於數據的需求是不一致的,比如手機端或者Web端又或者在低延遲的網絡環境或者高延遲的網絡環境。

因此為了優化客戶端的使用體驗,API Gateway可以對通用性的響應數據進行裁剪以適應不同客戶端的使用需求。同時還可以將多個API調用邏輯進行聚合,從而減少客戶端的請求數,優化客戶端用戶體驗

3、多渠道支持

當然我們還可以針對不同的渠道和客戶端提供不同的API Gateway,對於該模式的使用由另外一個大家熟知的方式叫Backend for front-end, 在Backend for front-end模式當中,我們可以針對不同的客戶端分別創建其BFF,進一步了解BFF可以參考這篇文章:Pattern: Backends For Frontends

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案例就配置完了

4、測試

啟動gateway-service-zuul-simple項目,在瀏覽器中訪問:http://localhost:8888/it/spring-cloud,看到頁面返回了:http://www.ityouknow.com/spring-cloud 頁面的信息,如下:

我們以前面文章的示例代碼spring-cloud-producer為例來測試請求的重定向,在配置文件中添加:

zuul.routes.hello.path=/hello/**
zuul.routes.hello.url=http://localhost:9000/

啟動spring-cloud-producer,重新啟動gateway-service-zuul-simple,訪問:http://localhost:8888/hello/hello?name=%E5%B0%8F%E6%98%8E,返回:hello 小明,this is first messge

說明訪問gateway-service-zuul-simple的請求自動轉發到了spring-cloud-producer,並且將結果返回。


### 服務化

通過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-eurekaspring-cloud-producergateway-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,測試返回結果和上述示例相同,說明spirng cloud zuul默認已經提供了轉發功能。

到此zuul的基本使用我們就介紹完了。關於zuul更高級使用,我們下篇再來介紹。

參考:

API網關那些兒

示例代碼


作者:純潔的微笑
出處:http://www.ityouknow.com/
版權歸作者所有,轉載請注明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM