API ゲートウェイ パターンとダイレクト クライアントからマイクロサービス間の通信

ヒント

このコンテンツは、.NET Docs で入手できる、またはオフラインで読み取ることができる無料のダウンロード可能な PDF として入手できる、コンテナー化された .NET アプリケーションの電子ブックである .NET マイクロサービス アーキテクチャからの抜粋です。

コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャの電子ブックの表紙サムネイル。

マイクロサービス アーキテクチャでは、各マイクロサービスは一連の (通常は) きめ細かいエンドポイントを公開します。 この事実は、このセクションで説明するように、クライアントからマイクロサービスへの通信に影響を与える可能性があります。

クライアントからマイクロサービスへの直接通信

考えられるアプローチは、クライアントからマイクロサービスへの直接通信アーキテクチャを使用することです。 この方法では、図 4-12 に示すように、クライアント アプリは一部のマイクロサービスに直接要求を行うことができます。

クライアントからマイクロサービスへの通信アーキテクチャを示す図。

図 4-12 クライアントからマイクロサービスへの直接通信アーキテクチャの使用

この方法では、各マイクロサービスにパブリック エンドポイントがあり、場合によってはマイクロサービスごとに異なる TCP ポートがあります。 特定のサービスの URL の例として、Azure の次の URL があります。

http://eshoponcontainers.westus.cloudapp.azure.com:88/

クラスターに基づく運用環境では、その URL はクラスターで使用されるロード バランサーにマップされ、マイクロサービス間で要求が分散されます。 運用環境では、マイクロサービスとインターネットの間に Azure Application Gateway などのアプリケーション 配信コントローラー (ADC) を使用できます。 このレイヤーは、負荷分散を実行するだけでなく、SSL 終了を提供することでサービスをセキュリティで保護する透過的な層として機能します。 この方法では、CPU を集中的に使用する SSL 終了やその他のルーティング作業を Azure Application Gateway にオフロードすることで、ホストの負荷が向上します。 いずれの場合も、ロード バランサーと ADC は論理アプリケーション アーキテクチャの観点から透過的です。

クライアントからマイクロサービスへの直接通信アーキテクチャは、特にクライアント アプリが ASP.NET MVC アプリのようなサーバー側の Web アプリケーションである場合に、小規模なマイクロサービス ベースのアプリケーションに十分な可能性があります。 ただし、大規模で複雑なマイクロサービス ベースのアプリケーションを構築する場合 (たとえば、多数のマイクロサービスの種類を処理する場合など)、特にクライアント アプリがリモート モバイル アプリまたは SPA Web アプリケーションである場合、そのアプローチはいくつかの問題に直面します。

マイクロサービスに基づいて大規模なアプリケーションを開発する場合は、次の質問を検討してください。

  • クライアント アプリでバックエンドへの要求の数を最小限に抑え、複数のマイクロサービスへのチャット通信を減らすにはどうすればよいですか?

複数のマイクロサービスと対話して 1 つの UI 画面を構築すると、インターネット全体のラウンド トリップの数が増えます。 この方法により、UI 側の待機時間と複雑さが増します。 理想的には、サーバー側で応答を効率的に集計する必要があります。 この方法では、複数のデータが並列に戻り、一部の UI で準備ができたらすぐにデータを表示できるため、待機時間が短縮されます。

  • 承認、データ変換、動的要求ディスパッチなどの横断的な懸念をどのように処理できますか。

すべてのマイクロサービスにセキュリティや承認などのセキュリティと横断的な懸念を実装するには、多大な開発作業が必要になる場合があります。 考えられるアプローチは、Docker ホストまたは内部クラスター内にそれらのサービスを配置して外部から直接アクセスを制限し、API ゲートウェイなどの一元的な場所にこれらの横断的な懸念事項を実装することです。

  • クライアント アプリは、インターネットに対応していないプロトコルを使用するサービスとどのように通信できますか?

サーバー側で使用されるプロトコル (AMQP やバイナリ プロトコルなど) は、クライアント アプリではサポートされていません。 そのため、要求は HTTP/HTTPS などのプロトコルを使用して実行し、後で他のプロトコルに変換する必要があります。 この状況 では、中間者 アプローチが役立ちます。

  • モバイル アプリ用に特に作成されたファサードを形成するにはどうすれば良いでしょうか。

複数のマイクロサービスの API は、さまざまなクライアント アプリケーションのニーズに合わせて適切に設計されていない可能性があります。 たとえば、モバイル アプリのニーズは、Web アプリのニーズとは異なる場合があります。 モバイル アプリの場合は、データ応答をより効率的にできるように、さらに最適化する必要がある場合があります。 この機能を実行するには、複数のマイクロサービスからのデータを集計し、1 つのデータ セットを返し、場合によってはモバイル アプリで必要ない応答のデータを削除します。 もちろん、そのデータを圧縮することもできます。 ここでも、このシナリオでは、モバイル アプリとマイクロサービスの間のファサードまたは API が便利です。

クライアントからマイクロサービスへの直接通信ではなく API ゲートウェイを検討する理由

マイクロサービス アーキテクチャでは、通常、クライアント アプリは複数のマイクロサービスの機能を使用する必要があります。 その消費が直接実行される場合、クライアントはマイクロサービス エンドポイントへの複数の呼び出しを処理する必要があります。 アプリケーションが進化し、新しいマイクロサービスが導入されたり、既存のマイクロサービスが更新されたりするとどうなりますか? アプリケーションに多数のマイクロサービスがある場合、クライアント アプリから非常に多くのエンドポイントを処理することは、悪夢になる可能性があります。 クライアント アプリはそれらの内部エンドポイントに結合されるため、将来マイクロサービスを進化させると、クライアント アプリに大きく影響する可能性があります。

そのため、中間レベルまたは間接階層 (ゲートウェイ) を持つことは、マイクロサービス ベースのアプリケーションに便利です。 API ゲートウェイがない場合、クライアント アプリはマイクロサービスに直接要求を送信する必要があり、次のような問題が発生します。

  • 結合: API ゲートウェイ パターンがない場合、クライアント アプリは内部マイクロサービスに結合されます。 クライアント アプリは、アプリケーションの複数の領域がマイクロサービスでどのように分解されるかを知る必要があります。 内部マイクロサービスを進化およびリファクタリングする場合、これらのアクションは、クライアント アプリからの内部マイクロサービスへの直接参照により、クライアント アプリに重大な変更を引き起こすため、メンテナンスに影響します。 クライアント アプリは頻繁に更新する必要があります。そのため、ソリューションの進化が困難になります。

  • ラウンド トリップが多すぎる: クライアント アプリの 1 つのページ/画面で、複数のサービスを複数回呼び出す必要がある場合があります。 この方法では、クライアントとサーバーの間で複数のネットワーク ラウンド トリップが発生し、待機時間が大幅に増加する可能性があります。 中間レベルで処理される集計により、クライアント アプリのパフォーマンスとユーザー エクスペリエンスが向上する可能性があります。

  • セキュリティの問題: ゲートウェイがない場合、すべてのマイクロサービスを "外部" に公開する必要があります。クライアント アプリで直接使用されていない内部マイクロサービスを非表示にした場合よりも攻撃対象領域が大きくなります。 攻撃対象領域が小さいほど、アプリケーションの安全性が高くなります。

  • 横断的な懸念事項: 公開されている各マイクロサービスは、承認や SSL などの問題を処理する必要があります。 多くの状況では、これらの懸念事項を 1 つの層で処理できるため、内部マイクロサービスが簡略化されます。

API ゲートウェイ パターンとは

複数のクライアント アプリを使用して大規模または複雑なマイクロサービス ベースのアプリケーションを設計および構築する場合は、 API ゲートウェイを検討することをお勧めします。 このパターンは、マイクロサービスの特定のグループに対して単一エントリ ポイントを提供するサービスです。 オブジェクト指向設計の ファサード パターン に似ていますが、この場合は分散システムの一部です。 API ゲートウェイ パターンは、クライアント アプリのニーズを考えながら構築するため、"フロントエンドのバックエンド" (BFF) とも呼ばれます。

そのため、API ゲートウェイはクライアント アプリとマイクロサービスの間に配置されます。 それは、要求をクライアントからサービスにルーティングするリバース プロキシとして機能します。 また、認証、SSL 終了、キャッシュなど、他の横断的な機能も提供できます。

図 4-13 は、少数のマイクロサービスだけで、カスタム API ゲートウェイをシンプルなマイクロサービス ベースのアーキテクチャに適合させる方法を示しています。

カスタム サービスとして実装された API ゲートウェイを示す図。

図 4-13 カスタム サービスとして実装された API ゲートウェイの使用

アプリは、個々のマイクロサービスに要求を転送するように構成された単一のエンドポイント (API ゲートウェイ) に接続します。 この例では、API ゲートウェイは、コンテナーとして実行されるカスタム ASP.NET Core WebHost サービスとして実装されます。

この図では、複数の異なるクライアント アプリに対応する 1 つのカスタム API ゲートウェイ サービスを使用することを強調することが重要です。 API Gateway サービスは、クライアント アプリとは異なるさまざまな要件に基づいて成長し、進化するため、この事実は重要なリスクになる可能性があります。 最終的には、ニーズが異なるため肥大化し、実質的にはモノリシック アプリケーションやモノリシック サービスに似ている可能性があります。 そのため、たとえば、クライアント アプリのフォーム ファクターの種類ごとに 1 つずつ、複数のサービスまたは複数の小さな API ゲートウェイで API ゲートウェイを分割することが非常に推奨されます。

API ゲートウェイ パターンを実装するときは注意が必要です。 通常、アプリケーションのすべての内部マイクロサービスを集約する単一の API ゲートウェイを用意することはお勧めしません。 その場合、モノリシック アグリゲーターまたはオーケストレーターとして機能し、すべてのマイクロサービスを結合することによってマイクロサービスの自律性に違反します。

そのため、API ゲートウェイは、ビジネス境界とクライアント アプリに基づいて分離する必要があり、すべての内部マイクロサービスの単一のアグリゲーターとして機能するわけではありません。

API Gateway 層を複数の API ゲートウェイに分割する場合、アプリケーションに複数のクライアント アプリがある場合は、複数の API ゲートウェイの種類を識別するときにプライマリ ピボットにすることができます。そのため、各クライアント アプリのニーズに応じて異なるファサードを作成できます。 このケースは"Backend for Frontend" (BFF) という名前のパターンです。このパターンでは、次の図に示すように、各 API ゲートウェイは、クライアント アプリの種類ごとに調整された異なる API を提供できます。場合によっては、クライアント フォーム ファクターに基づいて、複数の内部マイクロサービスを呼び出す特定のアダプター コードを実装します。

複数のカスタム API ゲートウェイを示す図。

図 4-13.1 複数のカスタム API ゲートウェイの使用

図 4-13.1 は、クライアントの種類によって分離された API ゲートウェイを示しています。1 つはモバイル クライアント用、1 つは Web クライアント用です。 従来の Web アプリは、Web API ゲートウェイを使用する MVC マイクロサービスに接続します。 この例では、複数の細かい API ゲートウェイを使用して簡略化されたアーキテクチャを示します。 この場合、各 API ゲートウェイで識別される境界は、純粋に "Backend for Frontend" (BFF) パターンに基づいているため、クライアント アプリごとに必要な API のみに基づいています。 ただし、大規模なアプリケーションでは、さらに進み、ビジネス境界に基づいて他の API ゲートウェイを 2 つ目の設計ピボットとして作成する必要があります。

API ゲートウェイ パターンの主な機能

API ゲートウェイでは、複数の機能を提供できます。 製品によっては、より豊富な機能やシンプルな機能が提供される場合があります。ただし、API Gateway の最も重要で基本的な機能は、次の設計パターンです。

リバース プロキシまたはゲートウェイ ルーティング。 API ゲートウェイは、内部マイクロサービスのエンドポイントに要求 (レイヤー 7 ルーティング、通常は HTTP 要求) をリダイレクトまたはルーティングするためのリバース プロキシを提供します。 ゲートウェイは、クライアント アプリの単一のエンドポイントまたは URL を提供し、内部的に内部マイクロサービスのグループに要求をマップします。 このルーティング機能は、クライアント アプリをマイクロサービスから切り離すのに役立ちますが、モノリシック API とクライアント アプリの間に API ゲートウェイを配置することでモノリシック API を最新化する場合にも便利です。その後、将来多くのマイクロサービスに分割されるまでレガシ モノリシック API を使用しながら、新しい API を新しいマイクロサービスとして追加することもできます。 API ゲートウェイを使用することで、クライアントアプリは使用中のAPIが内部マイクロサービスとして実装されているか、またはモノリシックAPIとして実装されているかを意識することはありません。さらに重要なのは、モノリシックAPIをマイクロサービスに進化させたりリファクタリングしたりする際、API Gatewayのルーティング機能により、クライアントアプリはURIの変更に影響を受けることはありません。

詳細については、「 ゲートウェイ ルーティング パターン」を参照してください。

集計を要求します。 ゲートウェイ パターンの一部として、複数の内部マイクロサービスを対象とする複数のクライアント要求 (通常は HTTP 要求) を 1 つのクライアント要求に集約できます。 このパターンは、クライアント ページ/画面に複数のマイクロサービスからの情報が必要な場合に特に便利です。 この方法では、クライアント アプリは、複数の要求を内部マイクロサービスにディスパッチする単一の要求を API ゲートウェイに送信し、結果を集計してすべてをクライアント アプリに返します。 この設計パターンの主な利点と目的は、クライアント アプリとバックエンド API の間のチャット性を減らすことです。これは、モバイル アプリやクライアント リモート ブラウザーの JavaScript から送信された SPA アプリからの要求など、マイクロサービスが存在するデータセンター外のリモート アプリにとって特に重要です。 サーバー環境で要求を実行する通常の Web アプリ (ASP.NET Core MVC Web アプリなど) の場合、待機時間はリモート クライアント アプリよりも非常に小さいため、このパターンはそれほど重要ではありません。

使用する API Gateway 製品によっては、この集計を実行できる場合があります。 ただし、多くの場合、API ゲートウェイのスコープの下に集計マイクロサービスを作成する方が柔軟性が高いので、コード (つまり C# コード) で集計を定義します。

詳細については、「 ゲートウェイの集計パターン」を参照してください。

横断的な問題またはゲートウェイのオフロード 各 API Gateway 製品によって提供される機能に応じて、個々のマイクロサービスからゲートウェイに機能をオフロードできます。これにより、横断的な懸念事項を 1 つの層に統合することで、各マイクロサービスの実装を簡略化できます。 このアプローチは、次の機能など、すべての内部マイクロサービスで適切に実装することが複雑になる可能性がある特殊な機能に特に便利です。

  • 認証と承認
  • サービス検出の統合
  • 応答のキャッシュ
  • 再試行ポリシー、サーキット ブレーカー、QoS
  • レート制限とスロットリング
  • 負荷分散
  • ログ記録、トレース、関連付け
  • ヘッダー、クエリ文字列、クレーム変換
  • IP 許可リスト

詳細については、「 ゲートウェイ オフロード パターン」を参照してください。

API Gateway 機能を使用した製品の使用

各実装によっては、API Gateway 製品によってさらに多くの横断的な問題が発生する可能性があります。 ここでは、次の内容について説明します。

Azure API Management

Azure API Management (図 4-14 に示すように) は、API ゲートウェイのニーズを解決するだけでなく、API から分析情報を収集するなどの機能を提供します。 API 管理ソリューションを使用している場合、API ゲートウェイはその完全な API 管理ソリューション内のコンポーネントにすぎません。

AZURE API Management を API ゲートウェイとして使用する方法を示す図。

図 4-14 API ゲートウェイに Azure API Management を使用する

Azure API Management は、API ゲートウェイと管理の両方のニーズ (ログ記録、セキュリティ、使用状況測定など) を解決します。この場合、Azure API Management のような製品を使用する場合、これらの種類の API ゲートウェイは "シンナー" であるため、単一の API ゲートウェイがある可能性があるという事実は、モノリシック コンポーネントに向かって進化する可能性のあるカスタム C# コードを実装しないことを意味します。

API Gateway 製品は通常、イングレス通信のリバース プロキシのように機能します。この場合、内部マイクロサービスから API をフィルター処理し、この単一層の発行済み API に承認を適用することもできます。

API Management システムから得られる分析情報は、API がどのように使用されているか、およびそれらがどのように実行されているかを理解するのに役立ちます。 このアクティビティを行うには、ほぼリアルタイムの分析レポートを表示し、ビジネスに影響を与える可能性のある傾向を特定します。 さらに、要求と応答のアクティビティに関するログを使用して、さらにオンラインおよびオフラインの分析を行うことができます。

Azure API Management を使用すると、キー、トークン、IP フィルタリングを使用して API をセキュリティで保護できます。 これらの機能を使用すると、柔軟できめ細かいクォータとレート制限を適用し、ポリシーを使用して API の形状と動作を変更し、応答キャッシュを使用してパフォーマンスを向上させることができます。

このガイドと参照サンプル アプリケーション (eShopOnContainers) では、Azure API Management などの PaaS 製品を使用せずにプレーン コンテナーに焦点を当てるために、アーキテクチャはシンプルでカスタムメイドのコンテナー化アーキテクチャに限定されています。 ただし、Microsoft Azure にデプロイされる大規模なマイクロサービス ベースのアプリケーションの場合は、運用環境の API ゲートウェイのベースとして Azure API Management を評価することをお勧めします。

オセロット

Ocelot は軽量 API ゲートウェイであり、よりシンプルなアプローチに推奨されます。 Ocelot は、特にシステムへの統合されたエントリ ポイントを必要とするマイクロサービス アーキテクチャ用に作成されたオープン ソースの .NET Core ベースの API ゲートウェイです。 軽量、高速、スケーラブルで、他の多くの機能の間でルーティングと認証を提供します。

eShopOnContainers 参照アプリケーション 2.0 で Ocelot を選択する主な理由は、Ocelot が .NET Core ライトウェイト API ゲートウェイであるためです。これは、Docker ホスト、Kubernetes などのマイクロサービス/コンテナーをデプロイするのと同じアプリケーションデプロイ環境にデプロイできるためです。また、.NET Core に基づいているため、クロスプラットフォームであるため、Linux または Windows にデプロイできます。

コンテナーで実行されているカスタム API ゲートウェイを示す前の図は、コンテナーとマイクロサービス ベースのアプリケーションで Ocelot を実行する方法を正確に示しています。

さらに、Apigee、Kong、MuleSoft、WSO2 などの API ゲートウェイ機能を提供する他の多くの製品が市場に存在し、サービス メッシュ イングレス コントローラー機能用の Linkerd や Istio などの他の製品もあります。

最初のアーキテクチャとパターンの説明セクションの後、次のセクションでは 、Ocelot を使用して API ゲートウェイを実装する方法について説明します。

API ゲートウェイ パターンの欠点

  • 最も重要な欠点は、API ゲートウェイを実装するときに、その層を内部マイクロサービスと結合することです。 このような結合では、アプリケーションに深刻な問題が発生する可能性があります。 Azure Service Bus チームのアーキテクトである Clemens Vaster は、GOTO 2016 の "メッセージングとマイクロサービス" セッションで、この潜在的な困難を "新しい ESB" と見なします。

  • マイクロサービス API ゲートウェイを使用すると、追加の単一障害点が発生する可能性があります。

  • API ゲートウェイでは、追加のネットワーク呼び出しにより応答時間が増加する可能性があります。 ただし、通常、この余分な呼び出しは、内部マイクロサービスを直接呼び出すのが煩雑すぎるクライアント インターフェイスを持つよりも影響が少なくなります。

  • 適切にスケールアウトしないと、API ゲートウェイがボトルネックになる可能性があります。

  • API ゲートウェイには、カスタム ロジックとデータ集計が含まれている場合、追加の開発コストと将来のメンテナンスが必要です。 開発者は、各マイクロサービスのエンドポイントを公開するために API ゲートウェイを更新する必要があります。 さらに、内部マイクロサービスでの実装の変更により、API ゲートウェイ レベルでコードが変更される可能性があります。 ただし、(Azure API Management を使用する場合と同様に) API Gateway がセキュリティ、ログ、バージョン管理を適用しているだけの場合、この追加の開発コストが適用されない可能性があります。

  • API ゲートウェイが 1 つのチームによって開発されている場合、開発のボトルネックが発生する可能性があります。 この側面は、さまざまなクライアント ニーズに対応するきめ細かい API ゲートウェイを複数用意する方が優れた方法であるもう 1 つの理由です。 また、内部マイクロサービスに取り組むさまざまなチームが所有する複数の領域またはレイヤーに、API ゲートウェイを内部的に分離することもできます。

その他のリソース

前へ次へ


その他のリソース