QiitaAzure + Java の企画も終わってしまいました、以前、 Azure Functions で Spring Cloud Functionを使う - Qiita という記事を書いたのですが、もうすこし Spring フレームワークの機能を使えないと思い Spring Retry の機能を Azure Function + Spring Cloud で試してみました。
Spring Retry
Spring フレームワーク上で、アノテーションベースでリトライ処理を書けたりする便利なライブラリです。Spring Retry 単体でコードベースでリトライを記述することもできます。
GitHub は、以下です。
ここでは、Spring Retry そのものの解説はしないので、ドキュメント等を当たってください。
Azure Function + Spring Cloud 上で使うには
結論から言えば、きちんと使えましたので、どのように実装したかを記録として残しておこうと思います。
ハンドラ(Trigger)から呼ばれる Function があり、そのメソッドに @Retryable
アノテーションを指定します。引数には、ハンドルする例外クラスを配列で指定し、試行回数などを指定します。リファレンスは以下の通りです。固定バックオフ、指数関数的バックオフなども指定できます。
以下の例では意図的に、例外をスローしています。関数は Function<I,O>
を実装しているのスロー句とかを勝手に拡張できませんので、検査例外を扱いたい場合は、未検査例外 RuntimeException
を継承したラッパーを用意する必要があります。
@Retryable(value = { UnwrapedIOException.class }, maxAttempts = 5)
public Mono<Greeting> apply(Mono<User> mono) {
logger.info("hello function");
if (Math.random() < 0.5) {
logger.error("Throw IOException.");
throw new UnwrapedIOException(new IOException("File not found :-)"));
}
return mono.map(user -> new Greeting("Hello, " + user.getName() + "!\n"));
}
@Recover
も指定できます。
@Recover
public String recoverBar(UnwrapedIOException exception) {
logger.error("----------------- error ---------------------");
return "error";
}
まとめ
前回は単純なDIでしたが、Spring Retry も動作確認できました。こういった決まり切った処理をフレームワーク側に任せられるのは便利ですね。また、なにか機能を試したいと思います。
補足&追記
Twitterでご指摘いただいてそれはまさにおっしゃる通りです。元々のサンプルを流量しつつ Spring フレームワークをどこまでAzure Functionで使えるかの実験をしていたので、あまり深く考えてませんでした。
といわけで Reactorのフレームワーク内でRetryできるならそれを使った方が良いでしょうという話です。