Java の信頼性の高い Web アプリ パターン - パターンを適用する

Azure App Service
Azure Front Door
Azure Cache for Redis
Java 用 Microsoft Authentication Library

この記事では、信頼性の高い Web アプリ パターンを適用する方法について説明します。 信頼性の高い Web アプリ パターンは、クラウドへの移行時に Web アプリを変更する方法 (再プラットフォーム) を定義する一連の原則と実装手法です。 クラウドで成功するために行う必要がある最小限のコード更新に焦点を当てています。

このガイダンスの適用を容易にするために、デプロイできる信頼性の高い Web アプリ パターンのリファレンス実装があります。

参照実装のアーキテクチャを示す図。リファレンス実装アーキテクチャのアーキテクチャ。このアーキテクチャの Visio ファイルをダウンロードします。

次のガイダンスでは、全体の例としてリファレンス実装を使用します。 信頼性の高い Web アプリ パターンを適用するには、適切に設計されたフレームワークの柱に沿った次の推奨事項に従います。

[信頼性]

信頼性により、顧客に確約したことをアプリケーションで確実に満たせるようにします。 詳細については、「信頼性の設計レビュー チェックリスト」を参照してください。 信頼性の高い Web アプリ パターンでは、信頼性を高めるためにコード レベルで 2 つの主要な設計パターン (再試行パターンとサーキット ブレーカー パターン) が導入されています。

再試行パターンを使用する

再試行パターンは、一時的なサービス中断 (一時的な障害と呼びます) に対処します。これは通常、数秒以内に解決されます。 これらの障害は多くの場合、クラウド環境でのサービス スロットリング、動的負荷分散、ネットワークの問題によって発生します。 再試行パターンを実装するには、失敗した要求を再送信し、例外をスローする前に構成可能な遅延と試行を許可する必要があります。

Resilience4j を使用して、Java で再試行パターンを実装します。 Resilience4j は、軽量でフォールト トレランスなライブラリです。 サーキット ブレーカー、レート リミッター、再試行、またはバルクヘッド設計パターンを使用して、機能インターフェイス、ラムダ式、およびメソッド参照を拡張するための高階関数 (デコレーター) を提供します。

例: リファレンス実装では、サービス プラン コントローラーの listServicePlans メソッドを再試行注釈で修飾することで、再試行パターンを追加します。 このコードは、最初の呼び出しが失敗した場合に、データベースからサービス プランの一覧への呼び出しを再試行します。

    @GetMapping("/list")
    @PreAuthorize("hasAnyAuthority('APPROLE_AccountManager')")
    @CircuitBreaker(name = SERVICE_PLAN)
    @Retry(name = SERVICE_PLAN)
    public String listServicePlans(Model model) {
        List<serviceplandto> servicePlans = planService.getServicePlans();
        model.addAttribute("servicePlans", servicePlans);
        return "pages/plans/list";
    }

リファレンス実装では、再試行の最大試行回数、待機時間、再試行する必要がある例外を含む再試行ポリシーを構成します。 再試行ポリシーは application.propertiesで構成されます。

サーキット ブレーカー パターンを使用する

再試行パターンとサーキット ブレーカー パターンをペアリングすると、一時的な障害に関連しないサービスの中断を処理するアプリケーションの機能が拡張されます。 サーキット ブレーカー パターンは、アプリケーションが応答しないサービスに継続的にアクセスすることを防ぎます。 サーキット ブレーカー パターンでは、アプリケーションが解放され、CPU サイクルの無駄を回避するため、アプリケーションはエンド ユーザーに対するパフォーマンスの整合性を維持します。 詳細については、「Spring Circuit Breaker」および「Resilience4j」のドキュメントを参照してください。

例: リファレンス実装では、サーキット ブレーカー属性を使用してメソッドを修飾することで、サーキット ブレーカー パターンを実装します。

セキュリティ

セキュリティは、重要なデータやシステムの意図的な攻撃や悪用に対する保証を提供します。 詳細については、「セキュリティの設計レビュー チェックリスト」を参照してください。 信頼性の高い Web アプリ パターンでは、マネージド ID を使用して ID 中心のセキュリティを実装します。 プライベート エンドポイント、Web アプリケーション ファイアウォール、および Web アプリへの制限付きアクセスにより、セキュリティで保護されたイングレスが提供されます。

最小限の特権を適用する

セキュリティと効率を確保するには、ユーザー (ユーザー ID) と Azure サービス (ワークロード ID) にのみ必要なアクセス許可を付与します。

ユーザー ID にアクセス許可を割り当てる

アプリケーションのニーズを評価して、重複のないすべてのユーザー アクションに対応するロール一式を定義します。 各ユーザーを最も適切なロールにマップします。 職務に必要なものにのみアクセスできることを確認します。

ワークロード ID にアクセス許可を割り当てる

データベースでの CRUD アクションやシークレットへのアクセスなど、操作に不可欠なアクセス許可のみを付与します。 ワークロード ID のアクセス許可は永続的であるため、ワークロード ID にジャスト・イン・タイムまたは短期のアクセス許可を提供することはできません。

  • ロールベースのアクセス制御 (RBAC) を使用します。 アクセス許可を割り当てるには、常に Azure RBAC から始めます。 それは正確な制御を提供し、アクセスが監査可能であり、粒度の細かいことを保証します。 Azure RBAC を使用して、サービスが目的の機能を実行するために必要なアクセス許可のみを付与します。

  • Azure サービス レベルのアクセス制御を補足します。 Azure RBAC が特定のシナリオに対応していない場合は、Azure サービス レベルのアクセス ポリシーを追加します。

詳細については、以下を参照してください:

認証と承認を構成する

認証と承認は、Web アプリケーションのセキュリティの重要な一部です。 認証は、ユーザーの ID を検証するプロセスです。 承認では、ユーザーがアプリケーション内で実行できるアクションを指定します。 目標は、セキュリティ体制を弱めることなく、認証と承認を実装することです。 この目標を達成するには、Azure アプリケーション プラットフォーム (Azure App Service) と ID プロバイダー (Microsoft Entra ID) の機能を利用する必要があります。

ユーザー認証を構成する

プラットフォームの機能を使用してユーザー認証を有効にして、Web アプリをセキュリティで保護します。 Azure App Service では、Microsoft Entra ID などの ID プロバイダーによる認証がサポートされ、コードから認証ワークロードがオフロードされます。

例: リファレンス実装では、ID プラットフォームとして Microsoft Entra ID を使用します。 Microsoft Entra ID では、プライマリ テナントにアプリケーションを登録する必要があります。 アプリケーションを登録することで、Web アプリへのアクセス権を取得するユーザーがプライマリ テナントに ID を確保できます。 次の Terraform コードは、アプリ固有の Account Manager ロールと共に Entra ID アプリ登録を作成します。

resource "azuread_application" "app_registration" {
  display_name     = "${azurecaf_name.app_service.result}-app"
  owners           = [data.azuread_client_config.current.object_id]
  sign_in_audience = "AzureADMyOrg"  # single tenant

  app_role {
    allowed_member_types = ["User"]
    description          = "Account Managers"
    display_name         = "Account Manager"
    enabled              = true
    id                   = random_uuid.account_manager_role_id.result
    value                = "AccountManager"
  }
}

Key Vault はクライアント構成データを安全に格納し、App Service プラットフォームは環境変数としてアプリに情報を公開します。

ID プロバイダーと統合する

Web アプリケーションを Microsoft Entra ID と統合して、安全な認証と承認を実現します。 Spring Boot Starter for Microsoft Entra ID は、Spring Security と Spring Boot を使用して簡単にセットアップできるように、このプロセスを合理化します。 さまざまな認証フロー、自動トークン管理、カスタマイズ可能な承認ポリシーと、Spring Cloud コンポーネントとの統合機能が提供されます。 これにより、手動ライブラリや設定の構成なしで、Microsoft Entra ID と OAuth 2.0 を Spring Boot アプリケーションに簡単に統合できます。

例: リファレンス実装では、Web アプリの ID プロバイダーとして Microsoft ID プラットフォーム (Microsoft Entra ID) を使用します。 ここでは、OAuth 2.0 の認証コード付与を使用して、Microsoft Entra アカウントでサインインします。 次の XML スニペットでは、OAuth 2.0 承認コード付与フローで必要な 2 つの依存関係を定義しています。 依存関係 com.azure.spring: spring-cloud-azure-starter-active-directory により、Spring Boot アプリケーションで Microsoft Entra の認証と承認が有効になります。 依存関係 org.springframework.boot: spring-boot-starter-oauth2-client により、Spring Boot アプリケーションで OAuth 2.0 の認証と承認が有効になります。

<dependency>
    <groupid>com.azure.spring</groupid>
    <artifactid>spring-cloud-azure-starter-active-directory</artifactid>
</dependency>
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-oauth2-client</artifactid>
</dependency>

詳細については、「Spring Security の Spring Cloud Azure サポート」を参照してください。

認証と認可ビジネス ルールを実装する

認証と承認のビジネス ルールを実装するには、さまざまなアプリケーションの機能とリソースに対するアクセス制御ポリシーとアクセス許可を定義する必要があります。 Microsoft Entra ID 用 Spring Boot Starter を使用するには、Spring Security を構成する必要があります。 このライブラリを使用すると、Microsoft Entra ID との統合が可能になり、ユーザーが安全に認証されるようになります。 Microsoft Authentication Library (MSAL) を構成して有効にすると、より多くのセキュリティ機能にアクセスできるようになります。 その機能には、トークン キャッシュとトークンの自動更新が含まれています。

例: リファレンス実装では、Contoso Fiber のアカウント管理システムのユーザー ロールの種類を反映したアプリ ロールが作成されます。 ロールは承認時にアクセス許可に変換されます。 CAMS のアプリ固有のロールの例としては、アカウント マネージャー、レベル 1 (L1) サポート担当者、フィールド サービス担当者などがあります。 Account Manager ロールには、新しいアプリ ユーザーとお客様を追加するためのアクセス許可があります。 Field Service の担当者は、サポート チケットを作成できます。 PreAuthorize 属性は、特定のロールへのアクセスを制限します。

    @GetMapping("/new")
    @PreAuthorize("hasAnyAuthority('APPROLE_AccountManager')")
    public String newAccount(Model model) {
        if (model.getAttribute("account") == null) {
            List<ServicePlan> servicePlans = accountService.findAllServicePlans();
            ServicePlan defaultServicePlan = servicePlans.stream().filter(sp -> sp.getIsDefault() == true).findFirst().orElse(null);
            NewAccountRequest accountFormData = new NewAccountRequest();
            accountFormData.setSelectedServicePlanId(defaultServicePlan.getId());
            model.addAttribute("account", accountFormData);
            model.addAttribute("servicePlans", servicePlans);
        }
        model.addAttribute("servicePlans", accountService.findAllServicePlans());
        return "pages/account/new";
    }
    ...

Microsoft Entra ID と統合するために、リファレンス実装では OAuth 2.0 承認コード付与フローが使用されます。 このフローにより、ユーザーは Microsoft アカウントでサインインできます。 次のコード スニペットは、認証と承認に Microsoft Entra ID を使用するように SecurityFilterChain を構成する方法を示しています。

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
public class AadOAuth2LoginSecurityConfig {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
            .and()
                .authorizeHttpRequests()
            .requestMatchers(EndpointRequest.to("health")).permitAll()
            .anyRequest().authenticated()
            .and()
                .logout(logout -> logout
                            .deleteCookies("JSESSIONID", "XSRF-TOKEN")
                            .clearAuthentication(true)
                            .invalidateHttpSession(true));
        return http.build();
    }
}
...

詳細については、以下を参照してください:

サービスの認証と承認を構成する

サービスの認証と承認を構成して、環境内のサービスに必要な機能を実行する権限を付与します。 Microsoft Entra ID のマネージド ID を使用して、サービス ID の作成と管理を自動化し、手動による資格情報管理を排除します。 マネージド ID を使用すると、Web アプリは Azure Key Vault やデータベースなどの Azure サービスに安全にアクセスできます。 また、Azure App Service へのデプロイの CI/CD パイプライン統合も容易になります。 ただし、ハイブリッド展開やレガシー システムなどのシナリオでは、引き続きオンプレミス認証ソリューションを使用して移行を簡略化します。 システムで最新の ID 管理アプローチの準備ができたら、マネージド ID に移行します。 詳細については、「マネージド ID の監視」を参照してください。

例: リファレンス実装では、データベースのオンプレミス認証メカニズム(ユーザー名とパスワード)が保持されます。 その結果、参照実装ではデータベース シークレットはキー コンテナーに保存されます。 Web アプリはマネージド ID (システム割り当て) を使用して、キー コンテナーからシークレットを取得します。

中央シークレット ストアを使用してシークレットを管理する

アプリケーションをクラウドに移動するときは、Azure Key Vault を使用して、そのようなすべてのシークレットを安全に格納します。 この一元化されたリポジトリでは、セキュリティで保護されたストレージ、キー ローテーション、アクセス監査、およびマネージド ID をサポートしていないサービスの監視が提供されます。 アプリケーション構成の場合は、「Azure App Configuration」が推奨されます。

例: リファレンス実装では、(1) PostgreSQL データベースのユーザー名とパスワード、(2) Redis Cache パスワード、(3) MSAL 実装に関連付けられている Microsoft Entra ID のクライアント シークレットが Key Vault に格納されます。

Key Vault を HTTP 要求フローに入れない

各 HTTP 要求中ではなく、アプリケーションの起動時に Key Vault からシークレットを読み込みます。 Key Vault は、デプロイ時に機密データを安全に格納および取得することを目的としています。 HTTP 要求内の高頻度アクセスは、Key Vault のスループット機能を超える可能性があり、要求の制限と HTTP 状態コード 429 エラーが発生する可能性があります。 詳細については、Key Vault のトランザクション制限に関する記事を参照してください。

Key Vault のシークレットのアクセスに 1 つのメソッドを使用する

Key Vault のシークレットにアクセスするように Web アプリを構成する場合、主に次の 2 つのオプションがあります。

  • App Service App 設定: App Service のアプリ設定を使用して、環境変数としてシークレットを直接挿入します。

  • 直接シークレット参照: アプリケーション コード内でシークレットを直接参照します。 アプリケーションが Key Vault と通信できるように、application.properties 向け Java アプリケーションなどの特定のリファレンスをアプリケーションのプロパティ ファイルに追加します。

これらのメソッドの 1 つを選択し、簡潔にし、不要な複雑さを避けるためにそのメソッドを使用することが重要です。 Key Vault と Spring アプリケーションの統合には、次のプロセスが含まれます。

  1. pom.xml ファイルに Azure Key Vault シークレットの Azure Spring Boot Starter 依存関係を追加します。
  2. アプリケーションで Key Vault エンドポイントを構成します。 これは、application.properties ファイルを使用するか、環境変数として実行できます。

例: リファレンス実装では、App Service のアプリ設定を使用し、シークレットを挿入します。

プライベート エンドポイントを使用する

サポートされているすべての Azure サービスについて、すべての運用環境でプライベート エンドポイントを使用します。 プライベート エンドポイントは、Azure 仮想ネットワーク内のリソースと Azure サービス間のプライベート接続を提供します。 既定では、ほとんどの Azure サービスへの通信はパブリック インターネットを通過します。 プライベート エンドポイントには、コードの変更、アプリの構成、接続文字列が必要ありません。 詳細については、プライベート エンドポイントを作成する方法およびエンドポイント セキュリティのベスト プラクティスに関する記事を参照してください。

例: リファレンス実装では、Key Vault、Azure Cache for Redis、Azure Database for PostgreSQL のプライベート エンドポイントを使用します。

Web アプリケーション ファイアウォールを使用する

Web アプリへの受信インターネット トラフィックはすべて、Web アプリケーション ファイアウォールを通過して、一般的な Web 攻撃から保護する必要があります。 パブリック ロード バランサーがある場合は、すべての受信インターネット トラフィックを強制的に通過させ、Web アプリケーション ファイアウォールを通過させます。 (1) Azure Front Door プライベート エンドポイントを使用することも、(2) X-Azure-FDID ヘッダー値で要求をフィルター処理することもできます。

App Service プラットフォームと Java Spring は、ヘッダー値でフィルター処理できます。 最初の選択肢として App Service を使用する必要があります。 プラットフォーム レベルでフィルター処理すると、不要な要求がコードに到達するのを防ぐことができます。 Web アプリケーション ファイアウォールを通過するトラフィックを構成する必要があります。 ホスト名、クライアント IP、その他の値に基づいてフィルター処理ができます。 詳細については、「元の HTTP ホスト名を保持する」を参照してください。

例: リファレンス実装では、運用環境のプライベート エンドポイントと開発環境の X-Azure-FDID ヘッダー値を使用します。

データベース セキュリティを構成

データベースに対する管理者レベルのアクセス権には、特権操作を実行するためのアクセス許可が付与されています。 特権操作には、データベースの作成と削除、テーブル スキーマの変更、ユーザーのアクセス許可の変更などがあります。 開発者は、多くの場合、データベースを維持したり、問題のトラブルシューティングを行ったりするために、管理者レベルのアクセス権を必要としています。

  • 永続的で高度なアクセス許可は避けます。 権限が必要な操作を実行するには、Just-In-Time アクセス権を開発者に付与します。 Just-In-Time アクセス権を使用するには、ユーザーは、一時的なアクセス許可を取得してから、権限が必要な操作を実行します。

  • アプリケーションには高度なアクセス許可を付与しません。 アプリケーション ID への管理者レベルのアクセス権は付与しないでください。 データベースへのアプリケーションの最小権限付きアクセスを構成します。 バグとセキュリティ侵害の影響範囲を限定します。 Azure PostgreSQL データベースにアクセスするには、主に 2 つの方法があります。 Microsoft Entra 認証または PostgreSQL 認証を使用できます。 詳細については、Azure PostgreSQL での JDBC の使用に関する記事を参照してください。

コストの最適化

コストの最適化とは、不要な費用と管理オーバーヘッドを削減する方法を検討することです。 詳細については、「コスト最適化の設計レビュー チェックリスト」を参照してください。 信頼性の高い Web アプリ パターンでは、よりコスト最適化された Web アプリを実現するために、適正規模の手法、オートスケール、効率的なリソース使用が実装されています。

各環境のリソースを合理化する

Azure サービスのさまざまなパフォーマンス レベルを理解し、各環境のニーズに適した SKU のみを使用します。 運用環境には、運用に必要なサービス レベル アグリーメント (SLA)、機能、スケールを満たす SKU が必要です。 ただし、非運用環境では通常は同じ機能は必要ありません。 さらに節約するには、Azure Dev/Test の価格オプションAzure の予約コンピューティングの Azure 節約プランを検討します。

例: Azure Dev/Test の価格はいずれのコンポーネントにも対応していないため、リファレンス実装では Azure Dev/Test の価格は使用されません。 この最初のクラウド収束フェーズが終わった後、同じデータベース エンジンを少なくとも 1 年間使用するという計画のまま進むのであれば、予約インスタンスとする最有力候補は Azure Database for PostgreSQL です。 参照実装には、異なる SKU をデプロイする省略可能なパラメーターがあります。 環境パラメーターは、開発 SKU を選択するように Terraform テンプレートに指示します。 次のコードは、この環境パラメーターを示しています。

azd env set APP_ENVIRONMENT prod

Contoso Fiber では、開発と運用のデプロイに Infrastructure as Code (IaC) テンプレートを使用します。 開発環境は、アプリ開発に必要なコストが最も低い SKU を使用して、コストを最適化します。 運用環境では、アプリケーションの運用サービス レベルの目標要件を満たす SKU を使用します。

自動スケールの使用

オートスケールを使用して、運用環境の水平スケーリングを自動化する必要があります。 パフォーマンス メトリックに基づく自動スケーリング。 アプリケーションのスケーリング条件がよくわからない場合、CPU 使用率のパフォーマンス トリガーが出発点として適しています。 Web アプリケーションの動作に対応するように、スケーリング トリガー (CPU、RAM、ネットワーク、ディスク) を構成して調整する必要があります。 需要の頻繁な変化に合わせて垂直方向にスケーリングしないでください。 コスト効率が低くなります。 詳細については、「Azure App Service でのスケーリング」および「Microsoft Azure での自動スケーリング」を参照してください。

リソースを効率的に使用する

効率的なリソースの使用には、無駄なく組織のニーズを満たすために、クラウド リソースの戦略的な管理と割り当てが含まれます。 不要なリソースの支出と管理のオーバーヘッドを最小限に抑えます。 リソース効率を向上させるには、次の推奨事項に従います。

  • 共有サービスを使用します。 特定のリソースを一元化して共有すると、コストの最適化と管理オーバーヘッドの削減が実現します。 たとえば、共有ネットワーク リソースをハブ仮想ネットワークに配置します。

  • 未使用の環境を削除します。 コストを最適化するには、時間外や休暇中に非運用環境を削除します。 Infrastructure as Code を使用すると、Azure リソースと環境全体を削除できます。 infrastructure-as-code テンプレートから削除するリソースの宣言を削除します。 後で必要なデータをバックアップします。 削除するリソースへの依存関係について理解します。 依存関係がある場合は、それらのリソースも更新または削除する必要があります。

  • 機能を併置します。 空き容量がある場合は、アプリケーション リソースと機能を 1 つの Azure リソースに併置します。 たとえば、複数の Web アプリで 1 つのサーバー (App Service プラン) を使用したり、1 つのキャッシュで複数のデータ型をサポートしたりできます。

オペレーショナル エクセレンス

オペレーショナル エクセレンスは、アプリケーションをデプロイし、それを運用環境で実行し続ける運用プロセスをカバーします。 詳細については、「オペレーショナル エクセレンスのデザイン レビュー チェック一覧」を参照してください。 信頼性の高い Web アプリ パターンは、インフラストラクチャのデプロイと監視用に Infrastructure as Code を実装します。

監視の構成

トレースとデバッグ用に、要求が失敗したときに診断できるようにログ記録を有効にする必要があります。 アプリケーションから収集する利用統計情報は、運用上のニーズに応える必要があります。 少なくとも、ベースライン メトリックに関するテレメトリを収集する必要があります。 標的を絞った改善を加えるのに役立つユーザーの動作に関する情報を収集する必要があります。

ベースライン メトリックを監視する

ワークロードではベースライン メトリックを監視する必要があります。 測定する重要なメトリックには、要求スループット、平均要求期間、エラー、依存関係の監視が含まれます。 この利用統計情報は Application Insights を使用して収集することをお勧めします。

例: リファレンス実装では、Application Insights を使用します。 Application Insights は、App Service の app_settings 構成の一部として Terraform を介して有効になります。

app_settings = {
    APPLICATIONINSIGHTS_CONNECTION_STRING = var.app_insights_connection_string
    ApplicationInsightsAgent_EXTENSION_VERSION = "~3"
    ...
}

Spring Boot では、Java 仮想マシン (JVM)、CPU、Tomcat など、Application Insights にいくつかのコア メトリックが登録されます。 Application Insights は、Log4j や Logback などのログ記録フレームワークから自動的に収集します。 詳細については、次を参照してください。

必要に応じてカスタム テレメトリとメトリックを作成します。

Application Insights のベースライン メトリックに加えて、ユーザーとアプリケーションのやり取りをより深く理解するためにカスタム テレメトリを作成する必要があります。 Application Insights を使用すると、カスタムの利用統計情報を収集できます。また、Micrometer を使用してカスタム メトリックを収集することもできます。 目標は、アプリケーションのパフォーマンスとユーザーの動作に関するより深い分析情報を得て、より多くの情報に基づいた意思決定と改善を行えるようにすることです。

ログ ベースのメトリックを収集する

重要なアプリケーションの正常性とメトリックをより詳細に把握するには、ログ ベースのメトリックを追跡します。 Application Insights で Kusto 照会言語 (KQL) クエリを使用して、データを検索および整理できます。 詳細については、「Application Insights ログベースのメトリック」および「Application Insights のログベースのメトリックと事前に集計されたメトリック」を参照してください。

プラットフォーム診断を有効にする

Azure の診断設定では、収集するプラットフォーム ログとメトリックと、それらを保存する場所を指定できます。 プラットフォーム ログは、診断情報と監査情報を提供する組み込みのログです。 プラットフォーム診断はほとんどの Azure サービスで有効にできますが、各サービスでは独自のログ カテゴリが定義されています。 各種 Azure サービスにはログのカテゴリがあって、そこから選べます。

  • サポートされているすべてのサービスの診断を有効にします。 Azure サービスはプラットフォーム ログを自動的に作成しますが、サービスが自動的に保存することはありません。 それには各サービスの診断設定を有効にする必要があります。また、診断をサポートするすべての Azure サービスで有効にしてください。

  • アプリケーション ログと同じ送信先に診断を送信します。 診断を有効にしたら、収集するログと、ログの送信先を選びます。 プラットフォーム ログはアプリケーション ログと同じ宛先に送信して、2 つのデータセットを関連付けることができるようにする必要があります。

例: リファレンス実装では、Terraform を使用して、サポートされているすべてのサービスで Azure 診断を有効にします。 次の Terraform コードは、App Service の診断設定を構成します。

# Configure Diagnostic Settings for App Service
resource "azurerm_monitor_diagnostic_setting" "app_service_diagnostic" {
  name                           = "app-service-diagnostic-settings"
  target_resource_id             = azurerm_linux_web_app.application.id
  log_analytics_workspace_id     = var.log_analytics_workspace_id
  #log_analytics_destination_type = "AzureDiagnostics"

  enabled_log {
    category_group = "allLogs"

  }

  metric {
    category = "AllMetrics"
    enabled  = true
  }
}

CI/CD パイプラインを使用する

デプロイを自動化するには、継続的インテグレーション/継続的デプロイ (CI/CD) パイプラインを統合します。 この自動化は、ソース管理から、テスト、ステージング、運用など、さまざまな App Service 環境に直接拡張する必要があります。 GitHub プロジェクト用の Azure DevOps または GitHub Actions を使用している場合は、Azure パイプラインを利用します。

  • 単体テストの統合。 App Services にデプロイする前に、パイプライン内のすべての単体テスト (JUnit を使用) の実行と受け渡しに優先順位を付けます。 SonarQube や JaCoCo などのコード品質とカバレッジ ツールを組み込んで、包括的なテスト カバレッジを実現します。

  • Java モック フレームワークを採用する。 外部エンドポイントを含むテストでは、Java モック フレームワーク (Mockito、EasyMock) を利用します。 これらのフレームワークを使用すると、シミュレートされたエンドポイントを作成できます。 これにより、実際の外部エンドポイントを構成し、環境間でテスト条件を統一する必要がなくなります。

  • セキュリティ スキャンを実行します。 静的アプリケーション セキュリティ テスト (SAST) を使用して、ソース コードのセキュリティ上の欠陥とコーディング エラーを見つけます。 さらに、ソフトウェア構成分析 (SCA) を実行して、サードパーティのライブラリとコンポーネントのセキュリティ リスクを調べます。 これらの分析用のツールは、GitHub と Azure DevOps の両方に簡単に統合できます。

運用デプロイの管理

コードを運用環境にデプロイするためのガイドラインを確立し、すべての運用デプロイの承認プロセスを作成する必要があります。

パフォーマンス効率

パフォーマンス効率とは、ユーザーからの要求に合わせて効率的な方法でワークロードをスケーリングできることです。 詳細については、「パフォーマンス効率の設計レビュー チェックリスト」を参照してください。 信頼性の高い Web アプリ パターンでは、キャッシュ アサイド パターンを使用して、要求の多いデータの待機時間を最小限に抑えます。

キャッシュ アサイド パターンを使用する

キャッシュ アサイド パターンは、メモリ内データ管理を向上させるキャッシュ戦略です。 このパターンにより、データ要求を処理し、キャッシュと永続的ストレージ (データベースなど) の間の整合性を確保する責任がアプリケーションに割り当てられます。 Web アプリは、データ要求を受信すると、最初にキャッシュを検索します。 データが見つからない場合は、データベースからデータを取得し、要求に応答し、それに応じてキャッシュを更新します。 この方法では、応答時間が短縮され、スループットが向上し、スケーリングの必要性が軽減されます。 また、プライマリ データストアの負荷を軽減し、停止リスクを最小限に抑えることで、サービスの可用性を強化します。

キャッシュの有効化

キャッシュを有効にするには、spring-boot-starter-cache パッケージを依存関係として pom.xml ファイルに追加します。 spring-boot-starter-cache パッケージは、既定値を使用して Redis キャッシュを構成します。 Web アプリのニーズに合わせて、application.properties ファイルの値または環境変数を更新する必要があります。 たとえば、 spring.cache.redis.time-to-live (ミリ秒単位) は、データがキャッシュに留まる時間を決定します。 Web アプリのニーズを満たす値を指定する必要があります。 最後に、@Cacheable 注釈を使用して、コードで必要なデータをキャッシュする必要があります。

必要性の高いデータをキャッシュする

最も頻繁にアクセスされるデータのキャッシュに優先順位を付けます。 ユーザー エンゲージメントとシステム パフォーマンスを促進する主要なデータ ポイントを特定します。 キャッシュアサイド パターンの有効性を最適化し、待機時間とデータベースの負荷を大幅に削減するために、これらの領域専用のキャッシュ戦略を実装します。 Azure Monitor を使用して、データベースの CPU、メモリ、ストレージを追跡します。 これらのメトリックは、より小さなデータベース SKU を使用できるかどうかを判断するのに役立ちます。

キャッシュ データを最新の状態に保つ

最新のデータベース変更と同期するように、定期的なキャッシュ更新をスケジュールします。 データ ボラティリティとユーザーのニーズに基づいて最適なリフレッシュ レートを決定します。 この方法により、アプリケーションはキャッシュ アサイド パターンを使用して、迅速なアクセスと最新の情報の両方を提供できます。

データの一貫性を確保する

データベース書き込み操作の直後にキャッシュを更新するメカニズムを実装します。 イベント駆動の更新または専用のデータ管理クラスを使用して、キャッシュの一貫性を確保します。 キャッシュとデータベースの変更を一貫して同期することは、キャッシュ アサイド パターンの主要な部分です。

: 次のコードは、spring-boot-starter-cache パッケージを依存関係として pom.xml ファイルに追加し、キャッシュを有効にします。

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-cache</artifactid>
</dependency>

リファレンス実装により、application.properties ファイル内の Redis が有効になります。

# Redis
spring.data.redis.ssl.enabled=true
spring.session.redis.namespace=spring:session

次のコードでは、getAccountDetail という名前のメソッドを定義しています。 このメソッドは、指定されたユーザー名に関連付けられているユーザー設定を取得します。 @Cacheable(value="account-details", key="#id")getAccountDetail メソッドに注釈を付け、キャッシュでユーザー設定をキャッシュするように Web アプリに指示します。

    @Cacheable(value="account-details", key="#id")
    public AccountDetail getAccountDetail(Long id) {
        Optional<Account> optionalAccount = accountRepository.findById(id);
        if (optionalAccount.isEmpty()) {
            throw new IllegalArgumentException("Account ID " + id + " does not exist");
        }

        Account account = optionalAccount.get();
        AccountDetail accountDetail = mapToAccountDetail(account);

        return accountDetail;
    }

データベースのパフォーマンス

データベースのパフォーマンスは、アプリケーションのパフォーマンスとスケーラビリティに影響を与える可能性があります。 データベースのパフォーマンスをテストして、最適化されていることを確認することが重要です。 重要な考慮事項としては、適切なクラウド リージョンの選択、接続プール、キャッシュアサイド パターン、クエリの最適化などがあります。

  • ネットワーク ホップをテストします。 アプリケーションをクラウドに移動すると、ネットワーク ホップが追加されてデータベースに待機時間が発生する可能性があります。 新しいクラウド環境で導入される追加のホップをテストする必要があります。

  • パフォーマンス ベースラインを確立します。 初期ベースラインとしてオンプレミスのパフォーマンス メトリックを使用して、クラウドのアプリケーション パフォーマンスと比較する必要があります。

  • Application Insights を使用する。 Application Insights には、データベース クエリと JDBC インターフェイスに関する詳細なメトリックが用意されています。 これを使用して、移植されたデータベースが SLA を満たしていることを確認したり、調整が必要なクエリを見つけたりする必要があります。 セキュリティとパフォーマンスの問題があるため、動的 SQL は使用しないでください。

  • 接続プールを使用します。 JDBC 接続プールを使用し、1 秒あたりのトランザクション (TPS) メトリックと SLA に基づいて微調整する必要があります。 データベース パフォーマンスの監視ツールを使用して、負荷がかかっている状態のデータベースのパフォーマンスのテストと評価を行う必要があります。

次のステップ

GitHub リポジトリの手順に従って、リファレンス実装をデプロイします。 次のリソースを使用して、クラウドのベスト プラクティスと移行の詳細を確認します。

クラウドのベスト プラクティス。 Azure の導入とアーキテクチャのガイダンスについては、次を参照してください。

より高いサービス レベル目標 (SLO) を必要とするアプリケーションについては、「ミッション クリティカルなワークロード」を参照してください。

移行ガイダンス。 次のツールとリソースは、オンプレミスのリソースを Azure に移行するのに役立ちます。

  • Azure Migrate では、Web アプリ、SQL Server、仮想マシンの評価と移行を処理する、Azure 向けの簡素化された移行、モダン化、最適化サービスが提供されます。
  • Azure データベースの移行ガイドには、さまざまなデータベースの種類のためのリソースと、移行シナリオ用に設計されたさまざまなツールが用意されています。
  • Azure App Service ランディング ゾーン アクセラレータでは、App Service デプロイのセキュリティ強化とスケーリングに関するガイダンスが提供されます。