フロントエンドのクライアント通信

ヒント

このコンテンツは eBook の「Azure 向けクラウド ネイティブ .NET アプリケーションの設計」からの抜粋です。.NET Docs で閲覧できるほか、PDF として無料ダウンロードすると、オンラインで閲覧できます。

Cloud Native .NET apps for Azure eBook cover thumbnail.

クラウドネイティブ システムでは、フロントエンド クライアント (モバイル、Web、デスクトップ アプリケーション) に、独立したバックエンド マイクロサービスと対話するための通信チャネルが必要です。

どのようなオプションがありますか?

図 4-2 では、わかりやすさを考慮して、フロントエンド クライアントがバックエンド マイクロサービスと "直接通信" しています。

Direct client to service communication

図 4-2 クライアントからサービスへの直接通信

この方法では、フロントエンド クライアントがアクセス可能なパブリックエンド ポイントが各マイクロサービスに用意されています。 運用環境では、マイクロサービスの前にロード バランサーを配置して、トラフィックを適切にルーティングします。

実装は簡単ですが、クライアントの直接通信は、シンプルなマイクロサービス アプリケーションでのみ許容されます。 このパターンは、フロントエンド クライアントをコア バックエンド サービスに密結合し、次のような多くの問題のきっかけとなります。

  • バックエンド サービスのリファクタリングに対するクライアントの脆弱性。
  • コア バックエンド サービスが直接公開される、より広範な攻撃面。
  • 各マイクロサービス間における横断的な問題の繰り返し。
  • 過度に複雑なクライアント コード - クライアントは、複数のエンドポイントを追跡し、回復力のある方法でエラーを処理する必要があります。

代わりに広く受け入れられているクラウド設計パターンは、フロントエンド アプリケーションとバックエンド サービスの間に API ゲートウェイ サービスを実装する方法です。 図 4-3 は、このパターンを示しています。

API Gateway Pattern

図 4-3 API ゲートウェイ パターン

上の図では、API ゲートウェイ サービスがバックエンド コア マイクロサービスをどのように抽象化しているかに注目してください。 これは Web API として実装され、"リバース プロキシ" として機能し、受信トラフィックを内部マイクロサービスにルーティングします。

このゲートウェイにより、クライアントは内部サービスのパーティション分割とリファクタリングから分離されます。 バックエンド サービスを変更する場合は、クライアントを中断することなく、ゲートウェイでサービスを調整できます。 また、ゲートウェイは ID、キャッシュ、回復性、測定、調整などの横断的な問題に対する防御の第一線でもあります。 これらの横断的な問題の多くは、バックエンド コア サービスからゲートウェイにオフロードすることができます。これにより、バックエンド サービスが簡素化されます。

シンプルかつ高速な API ゲートウェイの維持は慎重に行う必要があります。 通常、ビジネス ロジックはゲートウェイには関与しません。 複雑なゲートウェイはボトルネックになるリスクがあり、最終的にはそれ自体が一枚岩となります。 大規模なシステムでは、多くの場合、クライアントの種類 (モバイル、Web、デスクトップ) またはバックエンドの機能別にセグメント化された複数の API ゲートウェイを公開します。 フロントエンド用バックエンドのパターンは、複数のゲートウェイを実装するための方向性を提供します。 図 4-4 は、このパターンを示しています。

Backend for Frontend Pattern

図 4-4 フロントエンド用バックエンドのパターン

上の図では、クライアントの種類 (Web、モバイル、デスクトップ アプリ) に基づいて、受信トラフィックが特定の API ゲートウェイに送信されることに注目してください。 各デバイスの機能はフォーム ファクター、パフォーマンス、表示の制限事項によって大幅に異なるため、この方法は理にかなっています。 通常、モバイル アプリケーションが公開する機能は、ブラウザーやデスクトップ アプリケーションよりも少なくなっています。 各ゲートウェイは、対応するデバイスの機能に合わせて最適化できます。

シンプルなゲートウェイ

最初に、独自の API ゲートウェイ サービスを構築できます。 GitHub のクイック検索には、多くの例が用意されています。

シンプルな .NET クラウドネイティブ アプリケーションの場合は、Ocelot ゲートウェイを検討してください。 オープン ソースであり、.NET マイクロサービス用に作成されています。これは軽量かつ高速でスケーラブルです。 API ゲートウェイと同様に、主な機能は受信 HTTP 要求をダウンストリーム サービスに転送することです。 また、.NET ミドルウェア パイプラインで構成できるさまざまな機能をサポートしています。

YARP (Yet Another Reverse Proxy) は、Microsoft 製品チームのグループが主導するもう 1 つのオープン ソース リバース プロキシです。 YARP は、NuGet パッケージとしてダウンロード可能であり、ミドルウェアとして ASP.NET フレームワークにプラグインされ、高度にカスタマイズできます。 YARP には、さまざまな使用例が適切に文書化されています。

エンタープライズ クラウドネイティブ アプリケーションの場合、作業を始めるのに役立つマネージド Azure サービスがいくつかあります。

Azure Application Gateway

ゲートウェイの要件がシンプルな場合は、Azure Application Gateway を検討してください。 Azure PaaS サービスとして利用できるこのゲートウェイには、URL ルーティング、SSL 終端、Web アプリケーション ファイアウォールなどの基本的なゲートウェイ機能が含まれています。 このサービスでは、レイヤー 7 の負荷分散機能がサポートされます。 レイヤー 7 では、低レベルの TCP ネットワーク パケットだけでなく、HTTP メッセージの実際のコンテンツに基づいて要求をルーティングできます。

本書では、クラウドネイティブ システムを Kubernetes でホストするよう推奨しています。 コンテナー オーケストレーターである Kubernetes は、コンテナー化されたワークロードのデプロイ、スケーリング、および運用上の処理を自動化します。 Azure Application Gateway は、Azure Kubernetes Service クラスター用の API ゲートウェイとして構成できます。

Application Gateway イングレス コントローラーを使用すると、Azure Application Gateway が Azure Kubernetes Service を直接操作できるようになります。 図 4.5 は、このアーキテクチャを示しています。

Application Gateway Ingress Controller

図 4-5 Application Gateway イングレス コントローラー

Kubernetes には、Ingress と呼ばれる HTTP (レベル 7) の負荷分散をサポートする機能が組み込まれています。 Ingress では、AKS 内のマイクロサービス インスタンスを外部に公開する方法に関する一連のルールを定義します。 上の図では、イングレス コントローラーがクラスター用に構成されたイングレス ルールを解釈し、Azure Application Gateway を自動的に構成します。 これらのルールに基づいて、Application Gateway は AKS 内で実行されているマイクロサービスにトラフィックをルーティングします。 イングレス コントローラーは、イングレス ルールに対する変更をリッスンし、Azure Application Gateway に適切な変更を加えます。

Azure API Management

中規模から大規模のクラウドネイティブ システムでは、Azure API Management を検討してください。 これは、API ゲートウェイのニーズを解決するだけでなく、フル機能の開発者および管理エクスペリエンスを提供するクラウドベースのサービスです。 図 4-6 は API Management を示しています。

Azure API Management

図 4-6 Azure API Management

最初に、API Management は構成可能なルールとポリシーに基づいて、バックエンド サービスへのアクセスを制御できるゲートウェイ サーバーを公開します。 これらのサービスは、Azure クラウド、オンプレミスのデータセンター、または他のパブリック クラウドに配置できます。 どのユーザーがどのような処理を実行できるかは、API キーと JWT トークンによって決まります。 すべてのトラフィックは、分析のためにログに記録されます。

API Management には、サービス、ドキュメント、およびそれらを呼び出すためのサンプル コードへのアクセスを提供する開発者ポータルが用意されています。 開発者は、Swagger/OpenAPI を使用してサービス エンドポイントを検査し、その使用状況を分析できます。 このサービスは、.NET、Java、Golang などの主要な開発プラットフォームで動作します。

発行者ポータルでは、管理者が API を公開し、その動作を管理する管理ダッシュボードが公開されます。 サービス アクセスを許可し、サービスの正常性を監視して、サービス テレメトリを収集できます。 管理者は、動作に影響を及ぼすための "ポリシー" を各エンドポイントに適用します。 ポリシーは、それぞれのサービスの呼び出しに対して順番に実行する構築済みのステートメントです。 ポリシーは、着信呼び出し/発信呼び出し用に、またはエラー発生時に呼び出されるように構成されます。 ポリシーを組み合わせるときに決定論的な順序付けを可能にするために、さまざまなサービス スコープでポリシーを適用できます。 製品には、多数の構築済みのポリシーが付属しています。

次の例は、ポリシーがクラウドネイティブ サービスの動作にどのように影響するかを示したものです。

  • サービス アクセスを制限する。
  • 認証を適用する。
  • 必要に応じて、1 つのソースからの呼び出しを調整する。
  • キャッシュを有効にする。
  • 特定の IP アドレスからの呼び出しをブロックする。
  • サービスのフローを制御する。
  • 要求を SOAP から REST に、または別のデータ形式 (例: XML から JSON) に変換する。

Azure API Management は、任意の場所 (クラウドやデータセンター内) でホストされているバックエンド サービスを公開できます。 クラウドネイティブ システムで公開できるレガシ サービスについては、REST と SOAP API の両方がサポートされます。 その他の Azure サービスも API Management 経由で公開できます。 マネージド API は、Azure Service BusAzure Logic Apps などの Azure バッキング サービスの上に配置できます。 Azure API Management には負荷分散サポートが組み込まれていないため、負荷分散サービスと共に使用する必要があります。

次に示す 4 つのレベルの Azure API Management が提供されています。

  • 開発者
  • Basic
  • Standard
  • Premium

Developer レベルは、非運用のワークロードおよび評価用です。 他のレベルでは、より優れた能力、機能、高度なサービス レベル アグリーメント (SLA) が提供されます。 Premium レベルでは、Azure Virtual Network複数リージョンのサポートが提供されます。 すべてのレベルの価格は、1 時間あたりの固定価格です。

Azure クラウドは、Azure API Management 向けのサーバーレス レベルも提供します。 このサービスは "従量課金の価格レベル" とも呼ばれ、サーバーレス コンピューティング モデルを中心に設計された API Management の一種です。 前述の "事前に割り当てられた" 価格レベルとは異なり、従量課金レベルでは迅速なプロビジョニングとアクション課金制の価格が提供されます。

これにより、次のユース ケースで API ゲートウェイの機能が有効になります。

  • Azure FunctionsAzure Logic Apps などのサーバーレス テクノロジを使用して実装されたマイクロサービス。
  • Service Bus のキューやトピック、Azure Storage などの Azure バッキング サービスのリソース。
  • トラフィックが時折急増するが、ほとんどの時間は少ないままのマイクロサービス。

従量課金レベルは、同じ基のサービスの API Management コンポーネントを使用しますが、動的に割り当てられたリソースに基づいてまったく異なるアーキテクチャを採用しています。 これは、次に示すサーバーレス コンピューティング モデルと完全に整合しています。

  • 管理するインフラストラクチャがない。
  • アイドル容量がない。
  • 高可用性。
  • 自動スケーリング。
  • コストが実際の使用状況に基づく。

新しい従量課金レベルは、サーバーレス リソースを API として公開するクラウドネイティブ システムに適しています。

リアルタイム通信

リアルタイム (プッシュ) 通信は、HTTP 経由でバックエンドのクラウドネイティブ システムと通信するフロントエンド アプリケーション向けのもう 1 つのオプションです。 ティッカー、オンライン教育、ゲーム、ジョブの進行状況の更新などのアプリケーションは、バックエンドから即時かつリアルタイムに応答する必要があります。 通常の HTTP 通信では、新しいデータが利用可能になったことをクライアントが認識する方法がありません。 クライアントは、サーバーに対して継続的に要求を "ポーリング" または送信する必要があります。 "リアルタイム" 通信では、サーバーはいつでも新しいデータをクライアントにプッシュできます。

多くの場合、リアルタイム システムには、高頻度のデータ フローおよび多数の同時クライアント接続という特徴があります。 リアルタイム接続の手動による実装はすぐに複雑になり、接続されたクライアントに対するスケーラビリティと信頼性の高いメッセージングを実現するために、非単純なインフラストラクチャが必要になります。 Azure Cache for Redis のインスタンスと、クライアント アフィニティ用の固定セッションが構成された一連のロード バランサーを管理できます。

Azure SignalR Service は、クラウドネイティブ アプリケーション用にリアルタイム通信を簡素化するフル マネージド Azure サービスです。 容量のプロビジョニング、スケーリング、固定接続などの技術的な実装の詳細は削除されています。 これらは、99.9% のサービス レベル アグリーメントで対処されます。 重視するのはインフラストラクチャの組み込みではなくアプリケーションの機能です。

クラウドベースの HTTP サービスを有効にすると、ブラウザー、モバイル、デスクトップ アプリケーションなど、接続されたクライアントにコンテンツの更新を直接プッシュできます。 クライアントは、サーバーをポーリングすることなく更新されます。 Azure SignalR は、リアルタイム接続を作成する転送テクノロジ (WebSocket、Server-Side Events、Long Polling など) を抽象化します。 開発者は、接続されたクライアントのすべてまたは特定のサブセットに対するメッセージの送信に注力します。

図 4-7 は、Azure SignalR が有効になっているクラウドネイティブ アプリケーションに接続する一連の HTTP クライアントを示しています。

Azure SignalR

図 4-7 Azure SignalR

Azure SignalR Service のもう 1 つの利点として、サーバーレス クラウドネイティブ サービスが実装されます。 おそらくコードは、Azure Functions のトリガーを使用してオンデマンドで実行されます。 このシナリオは、コードによってクライアントとの接続が長時間維持されないため、注意が必要になる可能性があります。 Azure SignalR サービスでは、サービスが既に接続を管理しているため、このような状況に対処できます。

Azure SignalR Service は、Azure SQL Database、Service Bus、Azure Cache for Redis などの他の Azure サービスと密接に統合されているため、クラウドネイティブ アプリケーションの多くの可能性がもたらされます。