タスクの再試行
答えて
RetriableTasks
は、この投稿に記載されているとおりに使用できます。Retrying Operations in Java必要に応じて、待機アルゴリズムを簡単に変更することができます。
サンプルコード:
//creates a task which will retry 3 times with an interval of 5 seconds
RetriableTask r = new RetriableTask(3, 5000, new Callable(){
public Object call() throws Exception{
//put your code here
}
});
r.call();
これをコードベースから除外する1つのオプションは、アプリケーションのコンポーネント間でコマンドパターンを使用することです。 ビジネスメソッドの呼び出しをオブジェクトに変換すると、呼び出しを簡単に手渡すことができ、抽象的なRetryHandlerでコマンドを受け取り、再試行することができます。これは実際の呼び出しから独立していて、再利用可能でなければなりません。
ありがとうございましたJochen、これは、タスクがRunnableかCallableのいずれかのインスタンスなので、私が持っているものです。私は、リトライロジックやバックオフアルゴリズムの種類を指定するなどのオプションを提供するフレームワークであることを期待していました。 – Scruffers
私は気付いていません。それはかなり珍しいですが、私は同意します。我々は、ほとんどの場合、永続化レイヤと通信するときに楽観的な例外に対処するために再試行を使用します。 –
あなたが春を使用する場合:
//import the necessary classes
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
import org.springframework.batch.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.batch.retry.policy.SimpleRetryPolicy;
import org.springframework.batch.retry.support.RetryTemplate;
...
// create the retry template
final RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new SimpleRetryPolicy(5));
final ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
backOffPolicy.setInitialInterval(1000L);
template.setBackOffPolicy(backOffPolicy);
// execute the operation using the retry template
template.execute(new RetryCallback<Remote>() {
@Override
public Remote doWithRetry(final RetryContext context) throws Exception {
return (Remote) Naming.lookup("rmi://somehost:2106/MyApp");
}
});
より具体的には、Spring Batchを使用していて、依存関係が必要な場合。 – Jonathan
を、私はあなたが持つ任意のコーラブルを再試行することができ、かなり柔軟な再試行ユーティリティhere
を実装しています:
public static <T> T executeWithRetry(final Callable<T> what, final int nrImmediateRetries,
final int nrTotalRetries, final int retryWaitMillis, final int timeoutMillis,
final Predicate<? super T> retryOnReturnVal, final Predicate<Exception> retryOnException)
最大タイムアウトを指定して、即時遅延リトライを行い、結果または例外に基づいて判断を再試行します。
多かれ少なかれ柔軟性があるこの機能のいくつかの他のバージョンがあります。
私はまた、注釈RetryRetry Aspect
Failsafeをチェックして適用することができ様相を書かれています。これは、再試行を実行するためのシンプルな、ゼロ依存ライブラリだし、同期および非同期の再試行をサポートし、その他のJava 8の統合、イベントリスナー、他の非同期APIとの統合、:
RetryPolicy retryPolicy = new RetryPolicy()
.retryOn(ConnectException.class, SocketException.class);
.withMaxRetries(3);
Connection connection = Failsafe.with(retryPolicy).get(() -> connect());
は、はるかに簡単に取得していません。
私はすでに答えが1つありますが、それは3年前のことです。私はそれを追加しなければなりません。今、私は絶対的な愛guava-retryingプロジェクトを追加します。
それは依存としてGuavaを持っていませんが、私は著者がこのプロジェクトに触発されたと思います
。コードを見せてあげましょう。
Callable<Boolean> callable = new Callable<Boolean>() {
public Boolean call() throws Exception {
return true; // do something useful here
}
};
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
.retryIfExceptionOfType(IOException.class)
.retryIfRuntimeException()
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build();
try {
retryer.call(callable);
} catch (RetryException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
あなたは春を使用している場合は、それがSpring Retryライブラリを使用して非常にシンプルなです。
さて、春の再試行は、個々のライブラリー(以前それは春のバッチの一部であった)フレームワークです。
ステップ1:スプリングリトライの依存性を追加します。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
ステップ2:はあなた@Configuration
クラスのいずれかにアプリケーションやのmain()メソッドが含まれている、あなたのクラスに@EnableRetry
注釈を追加します。
ステップ3:あなたは、例外の場合には、再び呼び出す/再試行したいあなた方法へ@Retryable
注釈を追加します。
@Retryable(maxAttempts=5,backoff = @Backoff(delay = 3000))
public void retrySomething() throws Exception{
logger.info("printSomething{} is called");
throw new SQLException();
}
この@Retryable
注釈はretrySomething()
5回(含む第一の障害)を呼び出し/再試行されます。
現在のスレッドは、次の再試行の間に3000秒または3秒を待機します。
- 1. K8S再試行
- 2. RESTful POST再試行応答
- 3. wso2 esb再試行設定
どのようなタスクをやり直したいですか? – fmucar
@fatih - 問題はありません。タスクの再試行は抽象的な概念です。 – Scruffers
興味深いことに、再試行するアクションをいくつかのクラスで再試行するように誰もが思っています。私はむしろ 'boolean shallWeRetryOnceMore()'メソッドをバックオフ/リトライ戦略マネージャーとして実装し、呼び出されたときすぐに 'false'を返すか、バックオフアルゴリズムに応じて時間を待ってからtrueを返します。 – Harald