1. 概要

Zuul は、動的ルーティング、監視、復元力、およびセキュリティを提供するNetflixのエッジサービス(またはAPIゲートウェイ)です。

このチュートリアルでは、フォールバックを使用してZuulルートを構成する方法を見ていきます。

2. 初期設定

まず、2つのSpring Bootアプリケーションをセットアップします。 最初のアプリケーションでは、単純なRESTサービスを作成します。 一方、2番目のアプリケーションでは、Zuulプロキシを使用して、最初のアプリケーションのRESTサービスのルートを作成します。

2.1. シンプルなRESTサービス

アプリケーションが今日の天気情報をユーザーに表示する必要があるとしましょう。 そこで、 spring -boot-starter-web スターターを使用して、Spring Bootベースの気象サービスアプリケーションを作成します。

<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ゲートウェイアプリケーション

次に、2番目のSpring BootアプリケーションであるAPIGatewayを作成しましょう。 このアプリケーションでは、気象サービス用のズールルートを作成します。

また、気象サービスとZuulの両方がデフォルトで8080を使用するため、別のポート7070で実行するように構成します。

それでは、最初に spring-cloud-starter-netflix-zuulをpom.xmlに追加しましょう。

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

次に、@EnableZuulProxyアノテーションをAPIGatewayアプリケーションクラスに追加します。

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

}

最後に、 application.yml の気象サービスAPIに対して、リボンを使用してZuulルートを構成します。

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. ズールルートのテスト

この時点で、両方のSpring Bootアプリケーションは、Zuulプロキシを使用して気象サービスAPIを公開するように設定されています。

それでは、両方のアプリケーションを実行して、Zuulを介して気象サービスAPIを確認しましょう。

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

2.4. フォールバックなしのZuulルート障害のテスト

それでは、気象サービスのアプリケーションを停止して、ズール経由で気象サービスをもう一度確認しましょう。 その結果、応答にエラーメッセージが表示されます。

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

明らかに、これはユーザーが見たい応答ではありません。 したがって、これに対処する方法の1つは、気象サービスのズールルートのフォールバックを作成することです。

3. ルートのズールフォールバック

Zuulプロキシは負荷分散にリボンを使用し、リクエストはHystrixコマンドで実行されます。 その結果、ズールルートの障害は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);
        }
    }

}

ご覧のとおり、メソッドgetRouteおよびfallbackResponseをオーバーライドしました。 getRouteメソッドは、フォールバックを作成する必要があるルートのIDを返します。 一方、 fallbackResponseメソッドは、カスタムフォールバック応答を返します。この場合、タイプGatewayClientResponseのオブジェクトです。 GatewayClientResponse は、ClientHttpResponseの単純な実装です。

3.2. Zuulフォールバックのテスト

次に、気象サービス用に作成したフォールバックをテストしてみましょう。 したがって、API Gatewayアプリケーションを実行し、気象サービスアプリケーションが停止していることを確認します。

それでは、Zuulルートを介して気象サービスAPIにアクセスし、フォールバック応答の動作を確認しましょう。

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

4. すべてのルートのフォールバック

これまで、ルートIdを使用してZuulルートのフォールバックを作成する方法を見てきました。 ただし、アプリケーションで他のすべてのルートの汎用フォールバックも作成するとします。 これを行うには、ルート Id の代わりに、getRouteメソッドから*またはnullを返すFallbackProviderおよびの実装をもう1つ作成します。

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

5. 結論

このチュートリアルでは、Zuulルートのフォールバックを作成する例を見てきました。 また、すべてのZuulルートの一般的なフォールバックを作成する方法も確認しました。

いつものように、これらすべての例とコードスニペットの実装は、GitHubにあります。