第14回 MicroProfile Fault Tolerance(3) - 例で理解する設定編

| 5 min read
Author: toshio-ogiwara toshio-ogiwaraの画像

MicroProfile Fault Tolerance(MP Fault Tolerance)を紹介する最後は設定によるフォールトトレランス機能の指定です。今回も前回同様、MP Fault Toleranceから提供される機能とその設定を「こんなことをしたい」的な利用シーンごとに説明していきます。なお、MP Fault Toleranceの機能は豊富なため説明は前々回の基本機能編、前回の非同期編、そして今回の設定編と3回に分けて行っています。

記事はコードの抜粋を記載します。全体を見たい場合や動作を確認したい場合は以下のGitHubリポジトリを参照ください。

MicroProfileをテーマにブログを連載しています。他の記事もよければ以下のリンクからどうぞ!

Contents

Information

この記事はJava17+Helidon 3.0.1 + MicroProfile Fault Tolerance 4.0をもとに作成しています。
MicroProfile Fault Toleranceの詳細は公式マニュアルを参照くだい。

設定機能の概要

#

MP Fault Toleranceに対する指定は前回まで見てきたとおり、すべてアノテーションで行うことができますが、全体に対する指定やアノテーションで指定した属性値の上書きなどはMicroProfile Config[1]の設定ファイルで行うことができます。今回はこのMP Fault Toleranceの設定機能を設定例を交えながら説明していきます。

アノテーションで指定した設定を上書きしたい

#

次の3つのレベルでアノテーションで指定した属性値を上書きできます。

  • メソッドに指定されている個々のアノテーションに対する属性値の上書き
  • クラスに指定されているアノテーションに対する属性値の上書き
  • アプリケーション全体のアノテーションに対する属性値の上書き

上書きする際の設定キーの書式は以下になります。
<classname>/<methodname>/<annotation>/<parameter>

上記は一番細かいレベルのメソッドに指定されているアノテーション設定を上書きする書式となります。クラスに指定されているものを上書きする場合は<classname>が、アプリケーション全体の場合は<classname><methodname>の指定が不要となります。

それでは、以下のコードを題材にそれに対する設定例をみていきましょう。

package io.extact.sample;
...
@ApplicationScoped
@Timeout(500)
public class FtClient {
@Retry(maxRetries = 3, delay = 1000)
public void execA(String param) {
workA(param);
}
@Retry(maxRetries = 2, maxDuration = 100)
public String execB() {
return workB();
}
@Retry(maxRetries = 5)
@Fallback(fallbackMethod = "fallback")
public int execC(int count) {
return workC();
}
...
}

このコードに対し以下の設定をした場合、実行時にexecBmaxDuration属性の値が10000(msec)で上書きされます。なお、ここでの設定はすべてMicroProfile Config標準のmicroprofile-config.propertiesに対する例となります。

io.extact.sample.FtClient/execB/Retry/maxDuration=10000

次に以下の設定をした場合はクラスに指定されている@Timeoutvalue属性の値が10000(msec)で上書きされ、結果、実行時にexecA, execB, execCのタイムアウト値が10000(msec)になります。

io.extact.sample.FtClient/Timeout/value=10000

最後にアプリケーション全体に対する指定は次のとおりになります。この場合はすべての@Retryに対するmaxRetries属性の値が1で上書きされ、結果、アプリケーション全体でリトライ回数が1回に統一されます。

Retry/maxRetries=1
上書きできるものはアノテーションに指定がある属性のみ

設定で上書きできるのはあくまでもアノテーションに指定したもののみで、アノテーションに指定されていない属性を足したりすることできません。例えば次のようなアノテーション指定と設定があった場合、実行時の内容は@Retry(maxRetries = 3, delay = 1000)のままで、maxDuration=10000が追加されることはありません。

package io.extact.sample;
...
@ApplicationScoped
@Timeout(500)
public class FtClient {
@Retry(maxRetries = 3, delay = 1000)
public void execA(String param) {
workA(param);
}
}
io.extact.sample.FtClient/execA/Retry/maxDuration=10000

また、これはクラス指定にも同様にいえることで、次のように設定してもFtClientクラス全体に@Bulkhead(3)が追加されることはありません。

Bulkhead/value=3

設定は指定されたレベルで一致するアノテーション属性があった場合にその属性値を単純に上書きするのみで、ソースコードに指定されていない属性を追加することはありません。また、該当がない要素に対する設定は無視されます[2]

フォールトトレランス機能を個別に無効化したい

#

アプリケーションの稼働環境などによりタイムアウトやリトライなどのフォールトトレランス機能を無効化したい場合があります。このような場合は設定で個別に機能を無効化することができます。

この無効化する設定キーの書式は以下になります。
<classname>/<methodname>/<annotation>/enabled=false

設定方法は先ほどのアノテーションを上書きする場合と同じです。

# 1. メソッド単位で無効化
io.extact.sample.FtClient/execC/Retry/enabled=false
# 2. クラス単位で無効化
io.extact.sample.FtClient/Retry/enabled=false
# 3. アプリケーション単位で無効化
Retry/enabled=false

1.はメソッド個別に無効化する例で、2.はクラス、3.はアプリケーション全体で機能を無効化する例となります。

なお、無効化されている機能を環境変数などで有効化する場合はtrueを指定します。

フォールバック機能以外をすべて無効化したい

#

サービスメッシュなどアプリケーション外部の仕組みでフォールトトレランス機能を代替することを想定し、機能個別ではなくフォールバック以外の機能を一括して無効化する設定が用意されています。無効化対象からフォールバック機能が除かれるのはフォールバック処理はアプリケーションロジックであるため、アプリケーション外部の機能では代替できないことを想定してのためです。

この指定を行う場合は以下を設定します。
MP_Fault_Tolerance_NonFallback_Enabled=false

先ほどの個別の無効化機能で明示的にtrueで有効化されている機能がある場合は、そちらが優先されます。つまり、次のような設定がされている場合、フォールバック機能に加えバルクヘッド機能も有効となります。

MP_Fault_Tolerance_NonFallback_Enabled=false
Bulkhead/enabled=true

まとめ

#

MicroProfile Configの設定(機能)を使っているため、リトライ回数やタイムアウトなどの条件を環境変数を使って上書きすることができます。この辺りの値は最初から一発で決まるものではなく、また環境によっても調整が必要になることからリビルドせずに条件を変更できるのはとても便利です。また、このようなことを簡単にできるのがマイクロサービスに必要な仕様を一貫して提供するMicroProfileの利点といえます。


  1. MicroProfile Config(MP Config)は第6回 お手軽便利MicroProfile Configで詳しく説明しています。 ↩︎

  2. 無視されるのはいいのですが、Helidonの現状の実装では警告ログもでないため、 設定誤りに気づきづらいのが難点です。 ↩︎

豆蔵デベロッパーサイト - 先週のアクセスランキング
  1. Nuxt3入門(第1回) - Nuxtがサポートするレンダリングモードを理解する (2022-09-25)
  2. 自然言語処理初心者が「GPT2-japanese」で遊んでみた (2022-07-08)
  3. GitHub Codespaces を使いはじめる (2022-05-18)
  4. Jest再入門 - 関数・モジュールモック編 (2022-07-03)
  5. ORマッパーのTypeORMをTypeScriptで使う (2022-07-27)
  6. Nuxt3入門(第4回) - Nuxtのルーティングを理解する (2022-10-09)
  7. Nuxt3入門(第3回) - ユニバーサルフェッチでデータを取得する (2022-10-06)
  8. 第1回 OpenAPI Generator を使ったコード生成 (2022-06-04)
  9. Nuxt3入門(第8回) - Nuxt3のuseStateでコンポーネント間で状態を共有する (2022-10-28)
  10. Nuxt3入門(第2回) - 簡単なNuxtアプリケーションを作成する (2022-10-02)