12.2. マイクロサービスのヘルスチェック

ヘルスチェックは、マイクロサービスとその依存関係のステータスを検証するために使用できる特別な REST API 実装です。MicroProfile Health を使用すると、アプリケーションのマイクロサービスでそれらの健全性を自己チェックし、全体的なヘルスステータスが定義されたエンドポイントに公開されます。

ヘルスチェックは、依存関係、システムプロパティー、データベース接続、エンドポイント接続、リソースの可用性など、マイクロサービスが必要とするものをすべて評価できます。サービスは、MicroProfile Health によって提供される API を実装して可用性として報告します。マイクロサービスが利用可能になると、UP のステータスを報告します。マイクロサービスが利用できない場合は、DOWN のステータスを報告します。サービスオーソライザーはこれらのステータスレポートを使用して、アプリケーション内でマイクロサービスを管理し、スケーリングする方法を決定できます。ヘルスチェックは、Kubernetes の liveness および readiness プローブと対話すること もできます。

たとえば、マイクロサービスベースの銀行アプリケーションでは、ログインマイクロサービス、バランス転送マイクロサービス、および請求用のマイクロサービスにヘルスチェックを実装する場合があります。バランス転送マイクロサービスのヘルスチェックがバグまたはデッドロックを検出すると、DOWN ステータスを返します。この場合、/health/live エンドポイントが Kubernetes liveness プローブで設定されている場合、プローブはマイクロサービスを自動的に再起動します。マイクロサービスを再起動すると、ユーザーにダウンタイムやエラーが発生し、アプリケーション内の他のマイクロサービスの機能が維持されます。

12.2.1. MicroProfile Health エンドポイントおよびアノテーション

MicroProfile Health は、以下の 3 つのエンドポイントを提供します。

  • /health/ready: マイクロサービスの準備状態を返します。または、要求を処理する準備ができているかどうかを返します。このエンドポイントは Kubernetes の readiness プローブに対応します。
  • /health/live: マイクロサービスの liveness、またはバグまたはデッドロックが発生したかどうかを返します。このチェックに失敗すると、マイクロサービスは実行されず、停止できます。このエンドポイントは Kubernetes liveness プローブに対応します。これは、チェックに失敗した場合に Pod を自動的に再起動します。
  • /health: /health /live および /health/ ready エンドポイントからの応答を集約します。このエンドポイントは非推奨の @Health アノテーションに対応し、MicroProfile 1.0 との互換性を提供する場合にのみ利用できます。MicroProfile 2.0 以降を使用している場合は、代わりに /health/ready または /health/live エンドポイントを使用してください。

readiness または liveness ヘルスチェックを実装するには、コードに @Liveness または @Readiness アノテーションを追加します。これらのアノテーションは、提供されたエンドポイントを Kubernetes の liveness および readiness プローブにリンクします。

以下の例は、ヒープメモリーの使用状況をチェックする @Liveness アノテーションを示しています。メモリー消費が 90% 未満の場合は、UP ステータスを返します。メモリー使用量が 90% を超えると、DOWN ステータスが返されます。

@Liveness
@ApplicationScoped
public class MemoryCheck implements HealthCheck {
 @Override
 public HealthCheckResponse call() {
        // status is up if used memory is < 90% of max
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        long memUsed = memoryBean.getHeapMemoryUsage().getUsed();
        long memMax = memoryBean.getHeapMemoryUsage().getMax();

        HealthCheckResponse response = HealthCheckResponse.named("heap-memory")
                .withData("used", memUsed)
                .withData("max", memMax)
                .state(memUsed < memMax * 0.9)
                .build();
        return response;
    }
}

以下の例は、ヒープメモリー使用量が 90% 未満の場合に /health/live エンドポイントからの JSON 応答を示しています。最初のステータスは、エンドポイントから返されるすべてのヘルスチェックの全体的なステータスを示します。2 つ目のステータスは、前述の name の値で指定された特定のチェックのステータスを示しています。この例では ヒープメモリー です。全体的なステータスが UP になるようにするには、エンドポイントで実行されるすべてのチェックに渡す必要があります。

{
  "status": "UP",
  "checks": [
    {
      "name": "heap-memory",
      "status": "UP",
      "data": {
        "used": "1475462",
        "max": ”51681681"
      }
    }
  ]
}

以下の例は、利用可能なデータベース接続をチェックする @Readiness アノテーションを示しています。接続に成功すると、UP ステータスが返されます。接続が利用できない場合は、DOWN のステータスを返します。

@Readiness
@ApplicationScoped
public class DatabaseReadyCheck implements HealthCheck {

    @Override
    public HealthCheckResponse call() {

        if (isDBConnected()) {
           return HealthCheckResponse.up(“databaseReady”);
        }
        else {
           return HealthCheckResponse.down(“databaseReady”);
        }
    }
}

以下の例は、データベース接続が利用できない場合に、/health/ready エンドポイントからの JSON 応答を示しています。最初のステータスは、エンドポイントから返されるすべてのヘルスチェックの全体的なステータスを示します。2 つ目のステータスは、前述の name の値で指定された特定のチェックのステータスを示しています。この例では databaseReady です。エンドポイントで実行されるチェックに失敗した場合、全体のステータスは DOWN になり ます。

{
  "status": ”DOWN",
  "checks": [
    {
      "name": ”databaseReady",
      "status": ”DOWN",
    }
  ]
}