1. 概述
本文將探討負載均衡與 Zuul 和 Eureka 的工作原理。
我們將通過 Zuul 代理,將請求路由到 Spring Cloud Eureka 發現的 REST 服務。
2. 初步設置
我們需要按照《Spring Cloud Netflix-Eureka》文章所示,設置 Eureka 服務器/客户端。
3. 配置 Zuul
Zuul 在眾多功能中,負責從 Eureka 服務位置獲取信息,並進行服務器端負載均衡。
3.1. Maven 配置
首先,我們將 Zuul Server 和 Eureka 依賴項 添加到我們的 pom.xml 中:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>3.2. 與 Eureka 通信
其次,我們將添加必要的屬性到 Zuul 的 application.properties 文件中:
server.port=8762
spring.application.name=zuul-server
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761/eureka}
我們在這裏告訴 Zuul 註冊自身為服務,並在 Eureka 中運行,端口號為 8762。
接下來,我們將實現 主類,並添加 @EnableZuulProxy 和 @EnableDiscoveryClient。 @EnableZuulProxy 表示該類為 Zuul Server,@EnableDiscoveryClient 則表示該類為 Eureka Client。
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulConfig {
public static void main(String[] args) {
SpringApplication.run(ZuulConfig.class, args);
}
}我們將會將瀏覽器指向 http://localhost:8762/routes。 這應該會顯示出 所有可用的 Zuul 路由,這些路由是由 Eureka 發現的。
{"/spring-cloud-eureka-client/**":"spring-cloud-eureka-client"}現在,我們將使用 Eureka 客户端並通過 Zuul 代理路由進行通信。 將瀏覽器指向 http://localhost:8762/spring-cloud-eureka-client/greeting 應該會生成類似下面的響應:
Hello from 'SPRING-CLOUD-EUREKA-CLIENT with Port Number 8081'!4. 使用 Zuul 進行負載均衡
當 Zuul 接收到請求時,它會選擇一個可用的物理位置,並將請求轉發到實際的服務實例。 緩存服務實例的位置以及將請求轉發到實際位置的整個過程,無需任何額外的配置即可一應俱全。
在這裏,我們可以看到 Zuul 如何封裝了相同服務的三個不同實例:
內部,Zuul 使用 Netflix Ribbon 從服務發現(Eureka Server)中查找所有服務實例。
讓我們觀察當多個實例啓動時,這種行為。
4.1. 註冊多個實例
我們將首先啓動兩個實例(8081 和 8082 端口)。
一旦所有實例啓動完畢,您可以在日誌中觀察到實例的物理位置已註冊到 DynamicServerListLoadBalancer 中,並且路由已映射到 Zuul Controller,該控制器負責將請求轉發到實際的實例:
Mapped URL path [/spring-cloud-eureka-client/**] onto handler of type [class org.springframework.cloud.netflix.zuul.web.ZuulController]
Client:spring-cloud-eureka-client instantiated a LoadBalancer:
DynamicServerListLoadBalancer:{NFLoadBalancer:name=spring-cloud-eureka-client,
current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
Using serverListUpdater PollingServerListUpdater
DynamicServerListLoadBalancer for client spring-cloud-eureka-client initialized:
DynamicServerListLoadBalancer:{NFLoadBalancer:name=spring-cloud-eureka-client,
current list of Servers=[0.0.0.0:8081, 0.0.0.0:8082],
Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:2;
Active connections count: 0; Circuit breaker tripped count: 0;
Active connections per server: 0.0;]},
Server stats:
[[Server:0.0.0.0:8080; Zone:defaultZone;......],
[Server:0.0.0.0:8081; Zone:defaultZone; ......],注意:日誌已格式化,以提高可讀性。
4.2. 負載均衡示例
請導航到瀏覽器中 http://localhost:8762/spring-cloud-eureka-client/greeting 幾次。
每次訪問,您應該看到略有不同的結果:
Hello from 'SPRING-CLOUD-EUREKA-CLIENT with Port Number 8081'!Hello from 'SPRING-CLOUD-EUREKA-CLIENT with Port Number 8082'!Hello from 'SPRING-CLOUD-EUREKA-CLIENT with Port Number 8081'!每當 Zuul 接收到請求時,它會按照輪詢方式轉發到不同的實例。
如果啓動另一個實例並將其註冊到 Eureka,Zuul 將會自動將其註冊並開始將請求轉發到該實例:
Hello from 'SPRING-CLOUD-EUREKA-CLIENT with Port Number 8083'!我們還可以更改 Zuul 的負載均衡策略為任何其他 Netflix Ribbon 策略 – 更多信息請參見我們的 Ribbon 文章。
5. 結論
正如我們所見,Zuul 為所有 Rest Service 的實例提供了一個統一的 URL,並採用輪詢方式將請求轉發到其中一個實例,實現負載均衡。