Spring Cloud Netflixガイド - Hystrix

1概要

このチュートリアルでは、「Spring Cloud Netflix Hystrix」 - フォールトトレランスライブラリ - について説明します。このライブラリを使用して、アプリケーション内のさまざまなレベルでの障害連鎖に対する戦略を記述した「サーキットブレーカー」エンタープライズパターンを実装します。

原理は電子機器に似ています。

Hystrix は関連サービスへの呼び出しに失敗する方法を監視しています。そのような失敗があるなら、それはサーキットを開いて、フォールバックメソッドに呼び出しを進めます。

ライブラリは、しきい値までの障害に耐えることができます。それ以上に、それは回路を開いたままにします。これは、将来の失敗を防ぐために、後続のすべての呼び出しをフォールバックメソッドに転送することを意味します。これにより、関連サービスが障害状態から回復するための時間バッファーが作成されます。

2 RESTプロデューサー

Circuit Breaker パターンを示すシナリオを作成するには、最初にサービスが必要です。次のステップで作成するHystrix対応の「 REST Consumer 」のデータを提供するため、「 REST プロデューサー」と呼びます。

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

プロジェクト自体は意図的に単純化されています。これは、1つのリンクを持つコントローラインターフェイスで構成されています。 SpringBootApplication__]。

インターフェースから始めましょう。

public interface GreetingController {
    @GetMapping("/greeting/{username}")
    String greeting(@PathVariable("username") String username);
}

そして実装:

@RestController
public class GreetingControllerImpl implements GreetingController {

    @Override
    public String greeting(@PathVariable("username") String username) {
        return String.format("Hello %s!\n", username);
    }
}

次に、メインのアプリケーションクラスを書き留めます。

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

このセクションを完成させるために、やらなければならないことは、我々が聞いているアプリケーションポートを設定することです。デフォルトのポート8080は使用しません。次の手順で説明するアプリケーション用にポートを予約したままにする必要があるためです。

さらに、後で紹介するクライアントアプリケーションから「 REST Producer 」を検索できるように、アプリケーション名を定義しています。次の内容で application.properties を作成しましょう。

server.port=9090
spring.application.name=rest-producer

これで、curlを使用して「 REST Producer 」をテストできます。

$> curl http://localhost:9090/greeting/Cid
Hello Cid!

3 Hystrix を使ったRESTコンシューマ

デモンストレーションシナリオでは、 RestTemplate Hystrix を使用して、前の手順の REST サービスを利用しているWebアプリケーションを実装します。簡単にするために、これを「 RESTコンシューマ 」と呼びます。

その結果、https://search.maven.org/classic/#search%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring-cloud-を使用して新しいMavenプロジェクトを作成します。 starter-hystrix%22 _、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a %3A%22spring-boot-starter-web%22[spring-boot-starter-web] およびhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework。依存関係として、boot%22%20AND%20a%3A%22spring-boot-starter-thymeleaf%22[ spring-boot-start-thymeleaf_ ]。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

Circuit Breaker が機能するためには、 Hystix がlink:をスキャンして @ HystixCommand アノテーション付きメソッドのアノテーション付きクラスを探し、そのプロキシを実装してその呼び出しを監視します。

最初に @ Service クラスを作成し、それを @ Controller に注入します。/thymeleaf-in-spring-mvc[Thymeleafを使ったWebアプリケーション]というリンクを作成しているので、ビューとして機能するHTMLテンプレートも必要です。

これは、関連するフォールバックメソッドを使用して @ HystrixCommand を実装する、注入可能な @ Service になります。このフォールバックでは、「オリジナル」と同じ署名を使用する必要があります。

@Service
public class GreetingService {
    @HystrixCommand(fallbackMethod = "defaultGreeting")
    public String getGreeting(String username) {
        return new RestTemplate()
          .getForObject("http://localhost:9090/greeting/{username}",
          String.class, username);
    }

    private String defaultGreeting(String username) {
        return "Hello User!";
    }
}

RestConsumerApplication がメインのアプリケーションクラスになります。 @ EnableCircuitBreaker アノテーションは、互換性のある任意のCircuit Breaker__実装についてクラスパスをスキャンします。

Hystrix を明示的に使用するには、このクラスに @ EnableHystrix というアノテーションを付ける必要があります。

@SpringBootApplication
@EnableCircuitBreaker
public class RestConsumerApplication {
    public static void main(String[]args) {
        SpringApplication.run(RestConsumerApplication.class, args);
    }
}

GreetingService を使用してコントローラを設定します。

@Controller
public class GreetingController {

    @Autowired
    private GreetingService greetingService;

    @GetMapping("/get-greeting/{username}")
    public String getGreeting(Model model, @PathVariable("username") String username) {
        model.addAttribute("greeting", greetingService.getGreeting(username));
        return "greeting-view";
    }
}

これがHTMLテンプレートです。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Greetings from Hystrix</title>
    </head>
    <body>
        <h2 th:text="${greeting}"/>
    </body>
</html>

アプリケーションが定義済みのポートで待機していることを確認するために、 application.properties ファイルに次のコードを追加します。

server.port=8080

Hystixサーキットブレーカが動作していることを確認するには、「 REST Consumer 」を起動して、ブラウザでhttp://localhost:8080/get-greeting/Cidを指定します。通常の状況下では、以下が表示されます。

Hello Cid!

REST Producer 」の失敗をシミュレートするには、単にそれを停止します。ブラウザの更新が完了したら、 @ Service のfallbackメソッドから返される一般的なメッセージが表示されます。

Hello User!

4 Hystrix および Feign を使用したRESTコンシューマ

それでは、Spring RestTemplate の代わりに、宣言的なRESTクライアントとして Spring Netflix Feign を使用するように、前の手順からプロジェクトを変更します。

利点は、サービスの発見のために私たちのFeign Clientインターフェースが Spring Netflix Eureka を使うように後で簡単にリファクタリングできることです。

新しいプロジェクトを開始するには、 ' REST Consumer 'のコピーを作成し、 'REST Producer’とhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%を追加します22org.springframework.cloud%22%20AND%20a%3A%22spring-cloud-starter-feign%22[spring-cloud-starter-feign]依存関係として:

<dependency>
    <groupId>com.baeldung.spring.cloud</groupId>
    <artifactId>spring-cloud-hystrix-rest-producer</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>

これで、私たちの GreetingController を使ってFeign Clientを拡張することができました。 Hystrix フォールバックは、 @ Component のアノテーションが付けられた静的な内部クラスとして実装します。

あるいは、このフォールバッククラスのインスタンスを返す @ Bean アノテーション付きメソッドを定義することもできます。

@ FeignClient のnameプロパティは必須です。このプロパティが指定されている場合は、 Eureka Client を介したサービス検出またはURLを介したアプリケーションの検索に使用されます。サービス発見のためのSpring Netflix Eurekaの使用に関する詳細は、次のリンクを見てください:/spring-cloud-netflix-eureka[この記事に]:

@FeignClient(
  name = "rest-producer"
  url = "http://localhost:9090",
  fallback = GreetingClient.GreetingClientFallback.class
)
public interface GreetingClient extends GreetingController {

    @Component
    public static class GreetingClientFallback implements GreetingController {

        @Override
        public String greeting(@PathVariable("username") String username) {
            return "Hello User!";
        }
    }
}

RestConsumerFeignApplication に、 Feign 統合を有効にするための追加のアノテーション、実際には @ EnableFeignClients をメインアプリケーションクラスに追加します。

@SpringBootApplication
@EnableCircuitBreaker
@EnableFeignClients
public class RestConsumerFeignApplication {

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

グリーティングを取得するために、以前に注入した @ Service ではなく、自動配線されたFeign Clientを使用するようにコントローラを変更します。

@Controller
public class GreetingController {
    @Autowired
    private GreetingClient greetingClient;

    @GetMapping("/get-greeting/{username}")
    public String getGreeting(Model model, @PathVariable("username") String username) {
        model.addAttribute("greeting", greetingClient.greeting(username));
        return "greeting-view";
    }
}

この例を前の例と区別するために、 application.properties のアプリケーションリスニングポートを変更します。

server.port=8082

最後に、前のセクションのものと同様に、この Feign 対応の ' REST Consumer 'をテストします。期待される結果は同じであるはずです。

5 Hystrix によるキャッシュフォールバック

今、私たちのリンクにHystrixを追加するつもりです:/spring-cloud-secure-services[Spring Cloud]プロジェクト。このクラウドプロジェクトでは、データベースと対話して書籍の評価を取得する評価サービスを利用しています。

私たちのデータベースは需要のあるリソースであり、その応答待ち時間は時間によって異なる場合もあれば、使用できない場合もあります。

このシナリオでは、 Hystrix Circuit-Breaker がデータのキャッシュにフォールバックします。

5.1. セットアップと構成

spring-cloud-starter-hystrix 評価モジュールへの依存関係:

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

評価がデータベースで挿入/更新/削除されたとき、私たちは Repository を使ってRedisキャッシュに同じものを複製します。もしRedisについてもっと知りたいのなら、リンクをチェックしてください:/spring-data-redis-tutorial[この記事]

RatingService を更新して、データベースクエリメソッドをHystrixコマンドで @ HystrixCommand でラップし、Redisからの読み込みにフォールバックするように設定しましょう。

@HystrixCommand(
  commandKey = "ratingsByIdFromDB",
  fallbackMethod = "findCachedRatingById",
  ignoreExceptions = { RatingNotFoundException.class })
public Rating findRatingById(Long ratingId) {
    return Optional.ofNullable(ratingRepository.findOne(ratingId))
      .orElseThrow(() ->
        new RatingNotFoundException("Rating not found. ID: " + ratingId));
}

public Rating findCachedRatingById(Long ratingId) {
    return cacheRepository.findCachedRatingById(ratingId);
}

フォールバックメソッドはラップされたメソッドと同じシグネチャを持ち、同じクラスに存在する必要があることに注意してください。 findRatingById が失敗するか、または指定されたしきい値を超えて遅延すると、 Hystrix は__findCachedRatingByIdにフォールバックします。

Hystrix 機能は AOP アドバイスとして透過的に注入されるので、Springのトランザクションアドバイスのような他のアドバイスがある場合は、アドバイスが積み重ねられる順序を調整する必要があります。ここでは、SpringのトランザクションAOPアドバイスが Hystrix AOP アドバイスよりも優先順位が低くなるように調整しました。

@EnableHystrix
@EnableTransactionManagement(
  order=Ordered.LOWEST__PRECEDENCE,
  mode=AdviceMode.ASPECTJ)
public class RatingServiceApplication {
    @Bean
    @Primary
    @Order(value=Ordered.HIGHEST__PRECEDENCE)
    public HystrixCommandAspect hystrixAspect() {
        return new HystrixCommandAspect();
    }

   //other Beans, Configurations
}

ここでは、 Springのトランザクション AOP アドバイスが Hystrix AOP__アドバイスより優先順位が低くなるように調整しました。

5.2. Hystrixフォールバックのテスト

これで回路が構成されたので、リポジトリとやり取りする H2 データベースを停止してテストできます。しかし、最初に、組み込みデータベースとして実行するのではなく、 H2 インスタンスを外部プロセスとして実行しましょう。

H2 library (h2-1.4.193.jar)を既知のディレクトリにコピーしてH2サーバーを起動しましょう。

>java -cp h2-1.4.193.jar org.h2.tools.Server -tcp
TCP server running at tcp://192.168.99.1:9092 (only local connections)

このH2サーバーを指すように、 rating-service.properties のモジュールのデータソースURLを更新しましょう。

spring.datasource.url = jdbc:h2:tcp://localhost/~/ratings

Spring-Cloudシリーズの/spring-cloud-bootstrapping[article]から、実行中の外部H2インスタンスを停止することで各本の評価をテストすることができます。

H2 データベースにアクセスできない場合、 Hystrix は自動的に各書籍の評価を読むために Redis にフォールバックします。

この使用例を示すソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-bootstrap[ここ]にあります。

6. スコープを使う

通常、 @ HytrixCommand アノテーション付きメソッドはスレッドプールのコンテキストで実行されます。ただし、 @ SessionScope @ RequestScope など、ローカルスコープで実行する必要がある場合があります。これはコマンドアノテーションに引数を与えることで実現できます。

@HystrixCommand(fallbackMethod = "getSomeDefault", commandProperties = {
  @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")
})

7. Hystrix ダッシュボード

Hystrix の優れたオプション機能は、ダッシュボードでそのステータスを監視する機能です。

有効にするにはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring-cloud-starterを入れます。 -hystrix-dashboard%22[spring-cloud-starter-hystrix-dashboard]とhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND ' RESTコンシューマ 'のpom.xml内の%20a%3A%22スプリングブートスタータアクチュエータ%22[スプリングブートスタータアクチュエータ]:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

前者は @ EnableHystrixDashboard を使用して @ Configuration に注釈を付けることで有効にする必要があり、後者はWebアプリケーション内で必要なメトリックを自動的に有効にします。

アプリケーションの再起動が完了したら、ブラウザでhttp://localhost:8080/hystrixにアクセスし、 hystrix.stream のメトリクスURLを入力して監視を開始します。

最後に、次のようになります。

リンク:/uploads/Screenshot 20160819 031730-268x300-1-268x300.png[]

hystrix.stream 」を監視するのは良いことですが、複数の Hystrix 対応のアプリケーションを見なければならない場合、それは不便になります。この目的のために、 Spring Cloud Turbine と呼ばれるツールを提供します。これは、1つの Hystrix Dashboard に表示するためにストリームを集約することができます。

Turbine の設定はこの記事の範囲を超えていますが、その可能性についてはここで言及する必要があります。そのため、 Turbine Stream を使用して、メッセージング経由でこれらのストリームを収集することも可能です。

8結論

これまで見てきたように、これで Spring Netflix Hystrix Spring RestTemplate または Spring Netflix Feign を使って Circuit Breaker パターンを実装することができます。

つまり、「静的な」データではなく「デフォルトの」データを使用して、フォールバックを含むサービスを利用でき、このデータの使用状況を監視できます。

いつものように、ソースはhttps://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-hystrix[GitHub]にあります。