Hystrixを使用したRatpack
1. 序章
以前、Ratpackを使用して高性能でリアクティブなアプリケーションを構築する方法を示しました。
この記事では、NetflixHystrixをRatpackアプリケーションと統合する方法を見ていきます。
Netflix 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の最新バージョンは、ここにあります。 ratpack-hystrixには、ratpack-coreとhystrix-coreが含まれています。
Ratpackのリアクティブ機能を利用するには、ratpack-rxも必要です。
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-rx</artifactId>
<version>1.4.6</version>
</dependency>
ratpack-rxの最新バージョンは、ここにあります。
3. Hystrixコマンドで提供
Hystrixを使用する場合、基盤となるサービスは通常、HystrixCommandまたはHystrixObservableCommandでラップされます。 Hystrixは、同期、非同期、およびリアクティブの方法でこれらのコマンドを実行することをサポートしています。 これらの中で、リアクティブのみがノンブロッキングであり、公式に推奨されています。
次の例では、 Github RESTAPIからプロファイルをフェッチするエンドポイントをいくつか構築します。
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リアクティブ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";
}
}
ここでは、非ブロッキングではなくブロッキング HttpClient を使用します。これは、Hystrixが実際のコマンドの実行タイムアウトを制御して、[からの応答を取得するときに自分で処理する必要がないようにするためです。 X230X]将来。 これにより、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. 指標
Guiceモジュール– HystrixModule をRatpackレジストリに登録することで、リクエストスコープの指標をストリーミングし、GETエンドポイントを介してイベントストリームを公開できます。
serverSpec.registry(
Guice.registry(spec -> spec.module(new HystrixModule().sse())))
.handlers(c -> c.get("hystrix", new HystrixMetricsEventStreamHandler()));
HystrixMetricsEventStreamHandler は、 text / event-stream 形式でHystrixメトリックをストリーミングするのに役立ち、 HystrixDashboardでメトリックを監視できます。
スタンドアロンHystrixダッシュボードをセットアップし、Hystrixイベントストリームをモニターリストに追加して、Ratpackアプリケーションのパフォーマンスを確認できます。
Ratpackアプリケーションへのいくつかのリクエストの後、ダッシュボードにHystrix関連のコマンドが表示されます。
4.1. フードの下
HystrixModule では、Hystrix同時実行戦略がHystrixPlugin を介してHystrixに登録され、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ダッシュボードにプッシュしてアプリケーションのパフォーマンスをよりよく表示する方法を示しました。
いつものように、完全な実装はGithubプロジェクトにあります。