知識庫 / Spring / Spring Cloud RSS 訂閱

Zuul 路由回退

Spring Cloud
HongKong
6
01:08 PM · Dec 06 ,2025

1. 概述

Zuul 是 Netflix 提供的一種邊緣服務(或 API 網關),它提供動態路由、監控、彈性恢復和安全功能。

在本教程中,我們將學習如何 配置帶有回退功能的 Zuul 路由

2. 初步設置

首先,我們將設置兩個 Spring Boot 應用程序。在第一個應用程序中,我們將創建一個簡單的 REST 服務。另一方面,在第二個應用程序中,我們將使用 Zuul 代理為第一個應用程序的 REST 服務創建一個路由。

2.1. 一個簡單的 RESTful 服務

假設我們的應用程序需要向用户顯示今日天氣信息,我們將創建一個基於 Spring Boot 的天氣服務應用程序,並使用 spring-boot-starter-web 啓動器:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

現在,我們將為我們的天氣服務創建一個控制器:

@RestController
@RequestMapping("/weather")
public class WeatherController {

    @GetMapping("/today")
    public String getMessage() {
        return "It's a bright sunny day today!";
    }

}

現在,讓我們運行天氣服務並檢查天氣服務 API:

$ curl -s localhost:8080/weather/today
It's a bright sunny day today!

2.2 API 網關應用程序

現在,我們來創建第二個 Spring Boot 應用程序,即 API 網關。在這個應用程序中,我們將為我們的天氣服務創建一個 Zuul 路由。

由於我們的天氣服務和 Zuul 都默認使用 8080 端口,因此我們將配置它們運行在不同的端口,即 7070 端口。

因此,首先,我們將在 pom.xml 中添加 spring-cloud-starter-netflix-zuul

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

接下來,我們將添加 @EnableZuulProxy</em/> 標註到我們的API網關應用程序類中:

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

}

最後,我們將配置 Zuul 路由,使用 Ribbon,用於我們的天氣服務 API,在 application.yml 中:

spring:
   application:
      name: api-gateway
server:
   port: 7070
  
zuul:
   igoredServices: '*'
   routes:
      weather-service:
         path: /weather/**
         serviceId: weather-service
         strip-prefix: false

ribbon:
   eureka:
      enabled: false

weather-service:
   ribbon:
      listOfServers: localhost:8080

2.3. 測試 Zuul 路由

此時,兩個 Spring Boot 應用均已配置為通過 Zuul 代理暴露天氣服務 API。

因此,讓我們運行這兩個應用,並通過 Zuul 檢查天氣服務 API:

$ curl -s localhost:7070/weather/today
It's a bright sunny day today!

2.4. 在不啓用回退的情況下測試 Zuul 路由失敗

現在,讓我們停止天氣服務應用程序,並再次通過 Zuul 檢查天氣服務。 結果,我們會在響應中看到一個錯誤消息:

$ curl -s localhost:7070/weather/today
{"timestamp":"2019-10-08T12:42:09.479+0000","status":500,
"error":"Internal Server Error","message":"GENERAL"}

顯然,這並不是用户希望看到的響應。因此,我們可以通過創建一個 Zuul 服務的備用方案來解決這個問題。

3. Zuul 路由回退

Zuul 代理使用 Ribbon 進行負載均衡,請求在 Hystrix 命令中執行。因此,Zuul 路由上的故障會在 Hystrix 矩陣中出現

因此,為了為 Zuul 路由創建一個自定義回退,我們將創建一個類型為 FallbackProvider 的 Bean。

3.1. WeatherServiceFallback 類

在示例中,我們希望返回備用響應的消息,而不是我們之前看到的默認錯誤消息。因此,讓我們為天氣服務路由創建一個簡單的 FallbackProvider 實現:

@Component
class WeatherServiceFallback implements FallbackProvider {

    private static final String DEFAULT_MESSAGE = "Weather information is not available.";

    @Override
    public String getRoute() {
        return "weather-service";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
            return new GatewayClientResponse(HttpStatus.GATEWAY_TIMEOUT, DEFAULT_MESSAGE);
        } else {
            return new GatewayClientResponse(HttpStatus.INTERNAL_SERVER_ERROR, DEFAULT_MESSAGE);
        }
    }

}

如我們所見,我們已經覆蓋了 getRoutefallbackResponse 方法。 getRoute 方法返回用於創建備用響應的 Id。 另一方面,fallbackResponse 方法返回自定義備用響應,在本例中,它是一個類型為 GatewayClientResponse 的對象。 GatewayClientResponseClientHttpResponse 的簡單實現。

3.2. 測試 Zuul 降級功能

現在,讓我們測試我們為天氣服務創建的降級功能。因此,我們將運行 API 網關應用程序,並確保天氣服務應用程序已停止。

現在,讓我們通過 Zuul 路由訪問天氣服務 API,並觀察降級響應在行動中的效果:

$ curl -s localhost:7070/weather/today
Weather information is not available.

4. 所有路由的備用方案

迄今為止,我們已經瞭解瞭如何使用路由的 Id 創建 Zuul 路由的備用方案。但是,假設我們還想為應用程序中的所有其他路由創建通用的備用方案。我們可以通過創建另一個 FallbackProvider 的實現,並從 getRoute 方法中返回 *null,而不是路由的 Id 來實現:

@Override
public String getRoute() {
    return "*"; // or return null;
}

5. 結論

在本教程中,我們學習瞭如何為 Zuul 路由創建備用方案。我們還學習瞭如何為所有 Zuul 路由創建通用的備用方案。

發佈 評論

Some HTML is okay.