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-268×300-1-268×300.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]にあります。