Hystrixを使ったラットパック
1前書き
以前は、Ratpackを使用して高性能でリアクティブなアプリケーションを構築する方法について、/ratpack[表示]を参照してください。
この記事では、Netflix HystrixをRatpackアプリケーションと統合する方法について説明します。
Netflix Hystrixは、カスケード障害を防ぐためにアクセスポイントを隔離し、フォールトトレランスのためのフォールバックオプションを提供することによって、分散サービス間の相互作用の制御を支援します。それは私たちがより回復力のあるアプリケーションを構築するのを助けることができます。クイックレビューについては、/Introduction-to-hystrix[Hystrixの紹介]を参照してください。
それで、それが私たちがそれを使う方法です – 私たちはHystrixによってこれらの便利な機能で私たちのRatpackアプリケーションを強化するつもりです。
2 Mavenの依存関係
RatpackでHystrixを使うには、
pom.xml
プロジェクトでratpack-hystrix依存関係が必要です。
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-hystrix</artifactId>
<version>1.4.6</version>
</dependency>
ratpack-hystrixの最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22ratpack-hystrix%22%20AND%20g%3A%22io.ratpack%22にあります。[ここに]。
ratpack-hystrixにはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22io.ratpack%22%20AND%20a%3A%22ratpack-core%22[ratpack-core]が含まれています。
hystrix-core
。
Ratpackのリアクティブ機能を利用するには、ratpack-rxも必要です。
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-rx</artifactId>
<version>1.4.6</version>
</dependency>
ratpack-rxの最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22io.ratpack%22%20AND%20a%3A%22ratpack-rx%22にあります[ここに]。
3 Hystrix Command
を使ってサービングする
Hystrixを使うとき、基になるサービスは通常https://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/HystrixCommand.html[
HystrixCommand
]またはhttps://netflix.github.io/Hystrix/javadocでラップされています/com/netflix/hystrix/HystrixObservableCommand.html[
HystrixObservableCommand
]。
Hystrixは同期的、非同期的そして事後的な方法でこれらのコマンドの実行をサポートします。これらのうち、反応的なものだけが非閉塞性で公式に推奨されています。
-
以下の例では、https://developer.github.com/v3/[Github REST API]からプロファイルを取得するエンドポイントをいくつか構築します。
3.1. 反応的コマンド実行
まず、Hystrixを使ってリアクティブバックエンドサービスを構築しましょう。
public class HystrixReactiveHttpCommand extends HystrixObservableCommand<String> {
//...
@Override
protected Observable<String> construct() {
return RxRatpack.observe(httpClient
.get(uri, r -> r.headers(h -> h.add("User-Agent", "Baeldung HttpClient")))
.map(res -> res.getBody().getText()));
}
@Override
protected Observable<String> resumeWithFallback() {
return Observable.just("eugenp's reactive fallback profile");
}
}
ここではRatpackのリアクティブhttps://ratpack.io/manual/current/api/index.html?ratpack/http/client/HttpClient.html[
HttpClient
]を使用してGETリクエストを行います。
HystrixReactiveHttpCommand
はリアクティブハンドラとして実行できます。
chain.get("rx", ctx ->
new HystrixReactiveHttpCommand(
ctx.get(HttpClient.class), eugenGithubProfileUri, timeout)
.toObservable()
.subscribe(ctx::render));
エンドポイントは次のテストで確認できます。
@Test
public void whenFetchReactive__thenGotEugenProfile() {
assertThat(appUnderTest.getHttpClient().getText("rx"),
containsString("www.baeldung.com"));
}
3.2. 非同期コマンド実行
HystrixCommand
の非同期実行は、スレッドプール上のコマンドをキューに入れ、
Future
を返します。
chain.get("async", ctx -> ctx.render(
new HystrixAsyncHttpCommand(eugenGithubProfileUri, timeout)
.queue()
.get()));
HystrixAsyncHttpCommand
は次のようになります。
public class HystrixAsyncHttpCommand extends HystrixCommand<String> {
//...
@Override
protected String run() throws Exception {
return EntityUtils.toString(HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setDefaultHeaders(Collections.singleton(
new BasicHeader("User-Agent", "Baeldung Blocking HttpClient")))
.build().execute(new HttpGet(uri)).getEntity());
}
@Override
protected String getFallback() {
return "eugenp's async fallback profile";
}
}
ここでは、Hystrixに制御させたいので非ブロッキングの代わりにブロッキングhttps://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/HttpClient.html[
HttpClient
]を使用します
Future
から応答を受け取るときに自分自身でそれを処理する必要がないように、実際のコマンドの実行タイムアウト。これはまたHystrixが私達の要求を代替するかキャッシュすることを可能にします。
非同期実行でも予想される結果が得られます。
@Test
public void whenFetchAsync__thenGotEugenProfile() {
assertThat(appUnderTest.getHttpClient().getText("async"),
containsString("www.baeldung.com"));
}
** 3.3. 同期コマンド実行
同期実行は、現在のスレッドで直接コマンドを実行します。
chain.get("sync", ctx -> ctx.render(
new HystrixSyncHttpCommand(eugenGithubProfileUri, timeout).execute()));
HystrixSyncHttpCommand
の実装は
HystrixAsyncHttpCommand
とほぼ同じですが、異なるフォールバック結果が得られます。フォールバックしない場合は、リアクティブおよび非同期実行とまったく同じように動作します。
@Test
public void whenFetchSync__thenGotEugenProfile() {
assertThat(appUnderTest.getHttpClient().getText("sync"),
containsString("www.baeldung.com"));
}
4.メトリクス
リンクを登録することで:/ratpack-google-guice[Guiceモジュール] –
HystrixModule
をRatpackレジストリに登録して、リクエストのスコープをストリーミングできます。そして、
GET
エンドポイントを介してイベントストリームを公開します。
serverSpec.registry(
Guice.registry(spec -> spec.module(new HystrixModule().sse())))
.handlers(c -> c.get("hystrix", new HystrixMetricsEventStreamHandler()));
HystrixMetricsEventStreamHandler
は、https://のメトリックを監視できるように、
text/event-stream
形式でHystrixメトリックをストリーミングするのに役立ちますgithub.com/Netflix-Skunkworks/hystrix-dashboard[
Hystrix Dashboard
]。
standalone Hystrix dashboard
を設定し、Hystrixイベントストリームをモニターリストに追加して、Ratpackアプリケーションのパフォーマンスを確認できます。
リンク:/uploads/Snip20170815__1.png%20775w[]
Ratpackアプリケーションに何度かリクエストした後、ダッシュボードにHystrix関連のコマンドが表示されます。
4.1. フードの下
HystrixModule
では、http://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/strategy/concurrency/HystrixConcurrencyStrategy.html[Hystrix Concurrency Strategy]がhttps://github.com/Netflixを介してHystrixに登録されています。/Hystrix/wiki/Plugins[HystrixPlugin]はRatpackレジストリでリクエストコンテキストを管理します。これにより、各リクエストが始まる前にHystrixリクエストコンテキストを初期化する必要がなくなります。
public class HystrixModule extends ConfigurableModule<HystrixModule.Config> {
//...
@Override
protected void configure() {
try {
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new HystrixRegistryBackedConcurrencyStrategy());
} catch (IllegalStateException e) {
//...
}
}
//...
}
5結論
この簡単な記事では、HystrixをRatpackに統合する方法と、アプリケーションのパフォーマンスをより良く表示するためにRatpackアプリケーションのメトリックをHystrix Dashboardにプッシュする方法を説明しました。
いつものように、完全な実装はhttps://github.com/eugenp/tutorials/tree/master/ratpack[the Github project]にあります。