1.概要
リンク:/Introduction-to-hystrix[最後の記事]では、Hystrixの基本と、それがフォールトトレラントで回復力のあるアプリケーションの構築にどのように役立つかを調べました。
Hystrixを統合するためにこれらのアプリケーションを書き直すことは不可能かもしれませんが、Hystrixを統合するための非侵襲的な方法は可能です。 Spring AOP のヘルプ。
この記事では、Hystrixを既存のSpringアプリケーションと統合する方法を見ていきます。
2. HystrixからSpringアプリケーションへ
2.1. 既存のアプリケーション
前の記事で作成した RemoteServiceTestSimulator を呼び出すアプリケーションの既存のクライアント呼び出し元を見てみましょう。
@Component("springClient")
public class SpringExistingClient {
@Value("${remoteservice.timeout}")
private int remoteServiceDelay;
public String invokeRemoteServiceWithOutHystrix() throws InterruptedException {
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
}
}
上記のコードスニペットからわかるように、 invokeRemoteServiceWithOutHystrix メソッドは RemoteServiceTestSimulator リモートサービスへの呼び出しを行います。もちろん、実際のアプリケーションはこれほど単純ではありません。
2.2. 周辺アドバイスを作成する
Hystrixを統合する方法を示すために、このクライアントを例として使用します。
これを行うには、** invokeRemoteService が実行されたときに開始する Around アドバイスを定義します。
@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
public Object circuitBreakerAround(ProceedingJoinPoint aJoinPoint) {
return new RemoteServiceCommand(config, aJoinPoint).execute();
}
上記のアドバイスは、 @ HystrixCircuitBreaker のアノテーションが付けられたポイントカットで実行される Around アドバイスとして設計されています。
では、 HystrixCircuitBreaker アノテーションの定義を見てみましょう:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HystrixCircuitBreaker {}
2.3. Hystrix Logic
それでは、 RemoteServiceCommand を見てみましょう。 Hystrixの呼び出しロジックをカプセル化するために、サンプルコードでは静的な内部クラスとして実装されています。
private static class RemoteServiceCommand extends HystrixCommand<String> {
private ProceedingJoinPoint joinPoint;
RemoteServiceCommand(Setter config, ProceedingJoinPoint joinPoint) {
super(config);
this.joinPoint = joinPoint;
}
@Override
protected String run() throws Exception {
try {
return (String) joinPoint.proceed();
} catch (Throwable th) {
throw new Exception(th);
}
}
}
Aspect コンポーネントの実装全体はhttps://github.com/eugenp/tutorials/blob/master/hystrix/src/main/java/com/baeldung/hystrix/HystrixAspect.java[ここ]に見ることができます。
2.4. @ HystrixCircuitBreaker で注釈を付ける
アスペクトが定義されたら、以下に示すようにクライアントメソッドに @ HystrixCircuitBreaker のアノテーションを付けることができ、アノテーションが付けられたメソッドを呼び出すたびにHystrixが呼び出されます。
@HystrixCircuitBreaker
public String invokeRemoteServiceWithHystrix() throws InterruptedException{
return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
}
以下の統合テストは、HystrixルートとHystrix以外のルートの違いを示します。
2.5. 統合をテストする
デモンストレーションの目的で、Hystrixを使用する方法と使用しない方法の2つのメソッド実行ルートを定義しました。
public class SpringAndHystrixIntegrationTest {
@Autowired
private HystrixController hystrixController;
@Test(expected = HystrixRuntimeException.class)
public void givenTimeOutOf15000__whenClientCalledWithHystrix__thenExpectHystrixRuntimeException()
throws InterruptedException {
hystrixController.withHystrix();
}
@Test
public void givenTimeOutOf15000__whenClientCalledWithOutHystrix__thenExpectSuccess()
throws InterruptedException {
assertThat(hystrixController.withOutHystrix(), equalTo("Success"));
}
}
テストが実行されると、Hystrixなしのメソッド呼び出しはリモートサービスの実行時間全体を待ちますが、Hystrixルートはショートして、定義されたタイムアウト(10秒)の後に HystrixRuntimeException をスローします。
3.まとめ
異なる設定で行いたいリモートサービスコールごとに1つのアスペクトを作成できます。次の記事では、プロジェクトの最初からHystrixを統合することを見ていきます。
この記事のすべてのコードはhttps://github.com/eugenp/tutorials/tree/master/hystrix[GitHub]リポジトリにあります。