Javaでリトライをする方法

こんにちは。 エキサイト株式会社の三浦です。

アプリケーションコードを書く上で、特定の処理をリトライさせたい場合があります。 今回は、Java / Spring Bootでリトライする方法について説明していきます。

リトライ

アプリケーションコードを書く上で、どうしても失敗する可能性が消しきれない処理というものが存在します。 代表的なものとして「インターネットを介したAPIリクエスト」があり、以下のようにリクエスト元である我々ではどうしようもないエラーが発生し得ます。

  • リクエスト先APIに何かしら不具合が発生した
  • 通信をするためのネットワーク周りで何かしら障害が発生した

特にインターネットはベストエフォートなので、そもそも「100%常にリクエストが成功する」ことは保証していません。 そのため、上記のような場合でも我々が管理するアプリケーションは正しく動作することを考える必要があります。

これを解決する方法の一つが「リトライ」です。 すなわち、1回失敗しても「失敗した」判定はせず、規定回数に達するか成功するまで何度も処理を実行する、というものです。

Java / Spring Bootでのリトライ方法

このリトライ処理は、Java / Spring Boot環境では spring-retry というライブラリを使うことで簡単に実装できます。

build.gradle

必要なライブラリを設定します。 spring-retry だけでなく、 spring-boot-starter-aop も必要なので注意してください。

// バージョンは適宜変更してください
implementation 'org.springframework.retry:spring-retry:1.3.1'

// 設定にはこちらも必要になります
implementation 'org.springframework.boot:spring-boot-starter-aop'

設定ファイル

spring-retry の設定ファイルです。 ここで spring-retry を使えるようにします。

@Configuration
@EnableRetry
public class RetryConfig {}

リトライしたいメソッド

準備が整ったら、後はリトライしたいメソッドに @Retryable というアノテーションをつければリトライするようになります。 この時、 value に投げられたらリトライする例外クラスを、 backoff にリトライする際の挙動を書きます。

今回のサンプルコードでは、

  • SampleExceptionが投げられたらリトライする
  • リトライする際は、500ms空けて実行する
  • それ以外はデフォルトの動作

となっていますが、設定次第で挙動をカスタムできます。

@Retryable(value = {SampleException.class}, backoff = @Backoff(delay = 500))
public String sample() {
    return "Sample";
}

最後に

リトライは、アプリケーションが大きくなっていくと必要になる場面が増えてきます。 もちろん何でもかんでもリトライすればいいわけではないですが、適切に使用することでアプリケーションの信頼性は向上するはずです。

ぜひ使ってみてください。