ヒント
このコンテンツは、ASP.NET Core と Azure を使用した最新の Web アプリケーションの設計に関する電子ブックからの抜粋です。 .NET Docs またはオフラインで読み取ることができる無料のダウンロード可能な PDF として入手できます。
「優れたアーキテクチャがコストがかかると思われる場合は、不適切なアーキテクチャを試してください。 - Brian Foote と Joseph Yoder
ほとんどの従来の .NET アプリケーションは、1 つの IIS appdomain 内で実行されている実行可能ファイルまたは単一の Web アプリケーションに対応する単一のユニットとしてデプロイされます。 このアプローチは最も単純なデプロイ モデルであり、多くの内部および小規模のパブリック アプリケーションに非常によく役立ちます。 ただし、この単一の展開単位であっても、ほとんどの単純なビジネス アプリケーションは、いくつかの層への論理的な分離の恩恵を受けます。
モノリシック アプリケーションとは
モノリシック アプリケーションは、動作の観点から、完全に自己完結型のアプリケーションです。 操作を実行する過程で他のサービスやデータ ストアとやり取りする場合がありますが、動作の中核は独自のプロセス内で実行され、通常はアプリケーション全体が 1 つのユニットとしてデプロイされます。 このようなアプリケーションを水平方向にスケーリングする必要がある場合、通常、アプリケーション全体が複数のサーバーまたは仮想マシンに複製されます。
オールインワン アプリケーション
アプリケーション アーキテクチャの可能な限り少ない数のプロジェクトは 1 つです。 このアーキテクチャでは、アプリケーションのロジック全体が 1 つのプロジェクトに含まれており、1 つのアセンブリにコンパイルされ、1 つのユニットとして配置されます。
Visual Studio で作成した場合でも、コマンド ラインから作成した場合でも、新しい ASP.NET Core プロジェクトは、単純な "オールインワン" モノリスとして開始されます。 これには、プレゼンテーション、ビジネス、データ アクセス ロジックなど、アプリケーションのすべての動作が含まれます。 図 5-1 は、単一プロジェクト アプリのファイル構造を示しています。
図 5-1 ASP.NET Core アプリの単一プロジェクト。
1 つのプロジェクト シナリオでは、フォルダーを使用して懸念事項の分離を実現します。 既定のテンプレートには、モデル、ビュー、コントローラーの MVC パターン責任用の個別のフォルダーと、データとサービス用の追加フォルダーが含まれています。 この配置では、プレゼンテーションの詳細を Views フォルダーにできる限り制限し、データ アクセスの実装の詳細はデータ フォルダーに保持されるクラスに限定する必要があります。 ビジネス ロジックは、Models フォルダー内のサービスとクラスに存在する必要があります。
単純ですが、単一プロジェクトのモノリシック ソリューションにはいくつかの欠点があります。 プロジェクトのサイズと複雑さが増すにつれて、ファイルとフォルダーの数も増え続けます。 ユーザー インターフェイス (UI) の問題 (モデル、ビュー、コントローラー) は、アルファベット順にグループ化されていない複数のフォルダーに存在します。 この問題は、フィルターや ModelBinders などの追加の UI レベルのコンストラクトが独自のフォルダーに追加された場合にのみ悪化します。 ビジネス ロジックは Models フォルダーと Services フォルダーの間に散在しており、どのクラスのどのフォルダーが他のフォルダーに依存する必要があるかを明確に示す情報はありません。 このプロジェクト レベルでの組織の欠如は、しばしばスパゲッティ コードにつながります。
これらの問題に対処するために、多くの場合、アプリケーションはマルチプロジェクト ソリューションに進化し、各プロジェクトはアプリケーションの特定の レイヤー に存在すると見なされます。
レイヤーとは
アプリケーションが複雑になるにつれて、その複雑さを管理する 1 つの方法は、アプリケーションの責任や懸念に応じて分割することです。 このアプローチは、懸念事項の原則の分離に従い、開発者が特定の機能が実装されている場所を簡単に見つけられるように、成長するコードベースを整理し続けるのに役立ちます。 ただし、階層型アーキテクチャには、コード編成以外にも多くの利点があります。
コードをレイヤーにまとめることで、一般的な低レベル機能をアプリケーション全体で再利用できます。 この再利用は、コードを記述する必要が少ないことを意味し、単一の実装でアプリケーションを標準化できるため、 自分自身を繰り返さない (DRY) 原則に従うと便利です。
階層化アーキテクチャを使用すると、アプリケーションは、レイヤーが他のレイヤーと通信できる制限を適用できます。 このアーキテクチャは、カプセル化を実現するのに役立ちます。 レイヤーが変更または置き換えられると、そのレイヤーで動作するレイヤーのみが影響を受けます。 他のレイヤーに依存するレイヤーを制限することで、1 つの変更がアプリケーション全体に影響を与えないように、変更の影響を軽減できます。
レイヤー (およびカプセル化) により、アプリケーション内の機能を簡単に置き換えることができます。 たとえば、アプリケーションでは最初は永続化のために独自の SQL Server データベースを使用しますが、後でクラウドベースの永続化戦略を使用するか、Web API の背後で使用するかを選択できます。 アプリケーションが論理レイヤー内に永続化の実装を適切にカプセル化している場合、その SQL Server 固有のレイヤーは、同じパブリック インターフェイスを実装する新しいレイヤーに置き換えることができます。
アプリケーション レイヤーは、将来の要件の変更に応じて実装をスワップアウトする可能性に加えて、テスト目的で実装を簡単にスワップアウトすることもできます。 これらのレイヤーは、アプリケーションの実際のデータレイヤーまたは UI レイヤーに対して動作するテストを記述する必要なく、テスト時に、要求に対する既知の応答を提供する偽の実装に置き換えることができます。 通常、この方法では、アプリケーションの実際のインフラストラクチャに対してテストを実行する場合と比較して、テストの記述がはるかに簡単になり、実行がはるかに高速になります。
論理的な階層化は、エンタープライズ ソフトウェア アプリケーションでのコードの編成を改善するための一般的な手法であり、コードをレイヤーに編成する方法はいくつかあります。
注
レイヤーは、 アプリケーション内での論理的な分離を表します。 アプリケーション ロジックが個別のサーバーまたはプロセスに物理的に分散されている場合、これらの個別の物理デプロイ ターゲットは 階層と呼ばれます。 N 層アプリケーションを 1 つの層にデプロイすることは可能であり、非常に一般的です。
従来の "N 層" アーキテクチャ アプリケーション
レイヤーへのアプリケーション ロジックの最も一般的な編成を図 5-2 に示します。
図 5-2 一般的なアプリケーション レイヤー。
これらのレイヤーは、多くの場合、UI、BLL (ビジネス ロジック層)、DAL (データ アクセス層) と省略されます。 このアーキテクチャを使用すると、ユーザーは、BLL とのみ対話する UI レイヤーを介して要求を行います。 BLL は、データ アクセス要求のために DAL を呼び出すことができます。 UI レイヤーは DAL に直接要求を行う必要はありません。また、他の手段を介して永続化と直接やり取りする必要もありません。 同様に、BLL は DAL を経由して永続化とやり取りするだけです。 このように、各層には独自の既知の責任があります。
この従来の階層化アプローチの欠点の 1 つは、コンパイル時の依存関係が上から下に実行される点です。 つまり、UI レイヤーは、DAL に依存する BLL に依存します。 つまり、通常、アプリケーションで最も重要なロジックを保持する BLL は、データ アクセス実装の詳細 (多くの場合、データベースの存在) に依存します。 このようなアーキテクチャでのビジネス ロジックのテストは、多くの場合、テスト データベースを必要とするのは困難です。 次のセクションで説明するように、依存関係反転の原則を使用してこの問題に対処できます。
図 5-3 は、アプリケーションを 3 つのプロジェクト (またはレイヤー) に分割するソリューションの例を示しています。
図 5-3 3 つのプロジェクトを含む単純なモノリシック アプリケーション。
このアプリケーションは組織の目的で複数のプロジェクトを使用しますが、1 つのユニットとして展開され、クライアントは 1 つの Web アプリとして操作します。 これにより、非常に単純なデプロイ プロセスが可能になります。 図 5-4 は、このようなアプリが Azure を使用してホストされる方法を示しています。
図 5-4. Azure Web App の簡単なデプロイ
アプリケーションのニーズが高まるにつれて、より複雑で堅牢なデプロイ ソリューションが必要になる場合があります。 図 5-5 は、追加機能をサポートするより複雑なデプロイ計画の例を示しています。
図 5-5. Azure App Service への Web アプリのデプロイ
内部的には、このプロジェクトの組織は責任に基づいて複数のプロジェクトに分割され、アプリケーションの保守性が向上します。
このユニットをスケールアップまたはスケールアウトして、クラウドベースのオンデマンドスケーラビリティを活用できます。 スケールアップとは、アプリをホストするサーバーに CPU、メモリ、ディスク領域、またはその他のリソースを追加することを意味します。 スケールアウトとは、物理サーバー、仮想マシン、コンテナーのいずれであっても、そのようなサーバーのインスタンスを追加することです。 アプリが複数のインスタンスでホストされている場合、ロード バランサーを使用して個々のアプリ インスタンスに要求を割り当てます。
Azure で Web アプリケーションをスケーリングする最も簡単な方法は、アプリケーションの App Service プランでスケーリングを手動で構成することです。 図 5-6 は、アプリにサービスを提供しているインスタンスの数を構成するための適切な Azure ダッシュボード画面を示しています。
図 5-6 Azure での App Service プランのスケーリング。
クリーン アーキテクチャ
依存関係反転の原則と Domain-Driven 設計 (DDD) の原則に従うアプリケーションは、同様のアーキテクチャに到達する傾向があります。 このアーキテクチャは、長年にわたって多くの名前で使用されてきました。 最初の名前の 1 つは六角形アーキテクチャで、その後にポートとアダプターが続きました。 最近では、 オニオンアーキテクチャ または クリーンアーキテクチャとして引用されています。 後者の名前であるクリーン アーキテクチャは、この電子書籍のこのアーキテクチャの名前として使用されます。
eShopOnWeb 参照アプリケーションでは、クリーン アーキテクチャ アプローチを使用して、コードをプロジェクトに編成します。 独自の ASP.NET Core ソリューションの開始点として使用できるソリューション テンプレートは 、ardalis/cleanarchitecture GitHub リポジトリ内で、または NuGet からテンプレートをインストールすることで見つけることができます。
クリーン アーキテクチャでは、ビジネス ロジックとアプリケーション モデルがアプリケーションの中心に配置されます。 ビジネス ロジックがデータ アクセスやその他のインフラストラクチャの問題に依存するのではなく、この依存関係は逆になります。インフラストラクチャと実装の詳細は Application Core に依存します。 この機能は、Application Core で抽象化またはインターフェイスを定義することによって実現されます。これは、インフラストラクチャ レイヤーで定義された型によって実装されます。 このアーキテクチャを視覚化する一般的な方法は、オニオンに似た一連の同心円を使用することです。 図 5-7 は、このスタイルのアーキテクチャ表現の例を示しています。
図 5-7 クリーン アーキテクチャ。オニオン ビュー
この図では、依存関係が最も内側の円に向かって流れる。 Application Core は、この図の中心にある位置から名前を取得します。 また、図では、Application Core に他のアプリケーション レイヤーへの依存関係がないことを確認できます。 アプリケーションのエンティティとインターフェイスは、その中心にあります。 Application Core の外側にはまだありますが、通常は内部円で定義されたインターフェイスを実装するドメイン サービスです。 Application Core の外部では、UI レイヤーとインフラストラクチャ レイヤーの両方が Application Core に依存しますが、互いに依存しているわけではありません (必ずしも)。
図 5-8 は、UI と他のレイヤー間の依存関係をより適切に反映した、従来の水平レイヤー図を示しています。
図 5-8 クリーン アーキテクチャ;水平レイヤー ビュー
実線矢印はコンパイル時の依存関係を表し、破線の矢印はランタイムのみの依存関係を表します。 クリーン アーキテクチャでは、UI レイヤーはコンパイル時に Application Core で定義されたインターフェイスで動作し、インフラストラクチャ レイヤーで定義されている実装の種類について知る必要がないのが理想的です。 実行時には、これらの実装タイプはアプリの実行に必要であるため、依存性注入を介してアプリケーションコアのインターフェースに対して適切に設定されている必要があります。
図 5-9 は、これらの推奨事項に従ってビルドされた ASP.NET Core アプリケーションのアーキテクチャのより詳細なビューを示しています。
図 5-9 ASP.NET クリーン アーキテクチャに続くコア アーキテクチャの図。
Application Core はインフラストラクチャに依存しないため、このレイヤーの自動単体テストを簡単に記述できます。 図 5-10 と 5-11 は、テストがこのアーキテクチャにどのように適合するかを示しています。
図 5-10 分離して Application Core を単体テストする。
図 5-11 外部依存関係を持つインフラストラクチャ実装の統合テスト。
UI レイヤーはインフラストラクチャ プロジェクトで定義されている型に直接依存しないため、テストを容易にするため、またはアプリケーション要件の変化に対応するために、実装を簡単にスワップアウトできます。 ASP.NET Core の組み込みの使用と依存関係の挿入のサポートにより、このアーキテクチャは、単純でないモノリシック アプリケーションを構築するための最も適切な方法になります。
モノリシック アプリケーションの場合、Application Core、Infrastructure、UI プロジェクトはすべて 1 つのアプリケーションとして実行されます。 ランタイム アプリケーション アーキテクチャは、図 5-12 のようになります。
図 5-12 ASP.NET Core サンプルアプリのランタイム アーキテクチャ。
クリーン アーキテクチャでのコードの整理
クリーン アーキテクチャ ソリューションでは、各プロジェクトに明確な責任があります。 そのため、特定の種類は各プロジェクトに属しており、これらの種類に対応するフォルダーが適切なプロジェクトで頻繁に見つかります。
アプリケーションコア
Application Core は、エンティティ、サービス、インターフェイスを含むビジネス モデルを保持します。 これらのインターフェイスには、データ アクセス、ファイル システム アクセス、ネットワーク呼び出しなど、インフラストラクチャを使用して実行される操作の抽象化が含まれます。このレイヤーで定義されているサービスまたはインターフェイスは、UI またはインフラストラクチャに依存しない非エンティティ型で動作する必要がある場合があります。 これらは、単純なデータ転送オブジェクト (DTO) として定義できます。
Application Core の種類
- エンティティ (永続化されるビジネス モデル クラス)
- 集合体 (エンティティのグループ)
- インターフェイス
- ドメインサービス
- 仕様
- カスタム例外とガード句
- ドメイン イベントとハンドラー
インフラストラクチャ
インフラストラクチャ プロジェクトには、通常、データ アクセスの実装が含まれます。 一般的な ASP.NET Core Web アプリケーションでは、これらの実装には、Entity Framework (EF) DbContext、定義されているすべての EF Core Migration
オブジェクト、およびデータ アクセス実装クラスが含まれます。 データ アクセス実装コードを抽象化する最も一般的な方法は、 リポジトリの設計パターンを使用することです。
データ アクセスの実装に加えて、インフラストラクチャ プロジェクトには、インフラストラクチャの懸念事項と対話する必要があるサービスの実装が含まれている必要があります。 これらのサービスは、Application Core で定義されたインターフェイスを実装する必要があるため、インフラストラクチャには Application Core プロジェクトへの参照が必要です。
インフラストラクチャの種類
- EF Core の種類 (
DbContext
、Migration
) - データ アクセス実装の種類 (リポジトリ)
- インフラストラクチャ固有のサービス (
FileLogger
やSmtpNotifier
など)
UI レイヤー
ASP.NET Core MVC アプリケーションのユーザー インターフェイス レイヤーは、アプリケーションのエントリ ポイントです。 このプロジェクトは Application Core プロジェクトを参照する必要があり、その型は Application Core で定義されているインターフェイスを介して厳密にインフラストラクチャとやり取りする必要があります。 UI レイヤーでは、インフラストラクチャ レイヤーの種類に対する直接インスタンス化や静的呼び出しは許可されません。
UI レイヤーの種類
- コントローラー
- カスタム フィルター
- カスタム ミドルウェア
- 見解
- ViewModels(ビューモデル)
- スタートアップ
Startup
クラスまたはProgram.cs ファイルは、アプリケーションを構成し、実装の種類をインターフェイスに接続する役割を担います。 このロジックが実行される場所は、アプリの コンポジション ルートと呼ばれ、実行時に依存関係の挿入を適切に動作させるものです。
注
アプリの起動時に依存関係の挿入を結び付けるために、UI レイヤー プロジェクトでインフラストラクチャ プロジェクトを参照することが必要になる場合があります。 アセンブリから型を読み込むためのサポートが組み込まれているカスタム DI コンテナーを使用すると、この依存関係を最も簡単に排除できます。 このサンプルの目的上、最も簡単な方法は、UI プロジェクトがインフラストラクチャ プロジェクトを参照できるようにすることです (ただし、開発者はインフラストラクチャ プロジェクト内の型への実際の参照をアプリのコンポジション ルートに制限する必要があります)。
モノリシック アプリケーションとコンテナー
単一のモノリシックデプロイ ベースの Web アプリケーションまたはサービスを構築し、コンテナーとしてデプロイできます。 アプリケーション内では、モノリシックではなく、複数のライブラリ、コンポーネント、またはレイヤーに編成されている可能性があります。 外部的には、1 つのプロセス、単一の Web アプリケーション、または単一のサービスを持つ単一のコンテナーです。
このモデルを管理するには、アプリケーションを表す 1 つのコンテナーをデプロイします。 スケーリングするには、ロードバランサーを前面に配置して追加のコピーを増やすだけで済みます。 簡単な方法は、1 つのコンテナーまたは VM で 1 つのデプロイを管理することです。
図 5-13 に示すように、各コンテナー内に複数のコンポーネント/ライブラリまたは内部レイヤーを含めることができます。 ただし、"コンテナー は 1 つの処理を行い、1 つのプロセスで実行する" というコンテナーの原則に従うと、モノリシック パターンが競合する可能性があります。
このアプローチの欠点は、アプリケーションが拡大し、スケーリングが必要な場合/時です。 アプリケーション全体がスケーリングされる場合、実際には問題ではありません。 ただし、ほとんどの場合、アプリケーションのいくつかの部分がスケーリングを必要とするチョーク ポイントですが、他のコンポーネントの使用は少なくなります。
一般的な e コマースの例を使用して、スケーリングする必要がある可能性が高いのが製品情報コンポーネントです。 購入するよりも多くの顧客が製品を閲覧しています。 支払いパイプラインを使用するよりも多くの顧客がバスケットを使用しています。 コメントを追加したり、購入履歴を表示したりする顧客が少なくなります。 また、コンテンツとマーケティング キャンペーンを管理する必要がある従業員は、1 つのリージョンに少数しかない可能性があります。 モノリシック 設計をスケーリングすることで、すべてのコードが複数回デプロイされます。
"すべてをスケーリングする" 問題に加えて、1 つのコンポーネントに対する変更には、アプリケーション全体の完全な再テストと、すべてのインスタンスの完全な再デプロイが必要です。
モノリシック アプローチは一般的であり、多くの組織がこのアーキテクチャ アプローチを使用して開発しています。 多くのユーザーが十分な結果を得ているのに対し、他のユーザーは制限に達しています。 多くのユーザーがこのモデルでアプリケーションを設計しました。ツールとインフラストラクチャはサービス指向アーキテクチャ (SOA) の構築が難しすぎて、アプリが成長するまでニーズが見えなかったためです。 モノリシック アプローチの制限に達している場合は、コンテナーとマイクロサービスをより適切に活用できるようにアプリを分割することが、次の論理的な手順になる可能性があります。
Microsoft Azure でのモノリシック アプリケーションのデプロイは、インスタンスごとに専用 VM を使用して実現できます。 Azure 仮想マシン スケール セットを使用すると、VM を簡単にスケーリングできます。 Azure App Services では、VM を管理しなくても、モノリシック アプリケーションを実行し、インスタンスを簡単にスケーリングできます。 Azure App Services では、Docker コンテナーの単一インスタンスも実行できるため、デプロイが簡単になります。 Docker を使用すると、1 つの VM を Docker ホストとしてデプロイし、複数のインスタンスを実行できます。 図 5-14 に示すように、Azure バランサーを使用してスケーリングを管理できます。
さまざまなホストへのデプロイは、従来のデプロイ手法を使用して管理できます。 Docker ホストは、Docker 実行 などのコマンドを使用して手動で実行するか、継続的デリバリー (CD) パイプラインなどの自動化を使用して管理できます。
コンテナーとしてデプロイされたモノリシック アプリケーション
コンテナーを使用してモノリシック アプリケーションのデプロイを管理する利点があります。 コンテナーのインスタンスのスケーリングは、追加の VM をデプロイするよりもはるかに高速で簡単です。 仮想マシン スケール セットを使用して VM をスケーリングする場合でも、作成には時間がかかります。 アプリ インスタンスとしてデプロイすると、アプリの構成は VM の一部として管理されます。
Docker イメージとして更新プログラムをデプロイすると、はるかに高速でネットワーク効率が向上します。 Docker イメージは通常、数秒で開始され、ロールアウトが高速化されます。 Docker インスタンスの破棄は、 docker stop
コマンドを発行するのと同じくらい簡単で、通常は 1 秒未満で完了します。
コンテナーは本質的に設計上不変であるため、破損した VM について心配する必要はありません。一方、更新スクリプトでは、ディスク上に残されている特定の構成またはファイルを考慮し忘れる場合があります。
Docker コンテナーは、より単純な Web アプリケーションのモノリシックデプロイに使用できます。 このアプローチにより、継続的インテグレーションと継続的デプロイ パイプラインが向上し、デプロイから運用環境への成功を実現するのに役立ちます。 もう「自分のマシンでは動くのに、なぜ本番環境で動かないのか?」ということはありません。
マイクロサービス ベースのアーキテクチャには多くの利点がありますが、これらの利点には複雑さが増します。 コストがメリットを上回る場合があるため、1 つのコンテナーまたは少数のコンテナーで実行されるモノリシックデプロイ アプリケーションの方が適しています。
モノリシック アプリケーションは、適切に分離されたマイクロサービスに簡単に分解できない場合があります。 マイクロサービスは互いに独立して動作し、回復性の高いアプリケーションを提供する必要があります。 アプリケーションの独立した機能スライスを提供できない場合、分離すると複雑さが増すだけです。
アプリケーションでは、機能を個別にスケーリングする必要がまだない場合があります。 多くのアプリケーションは、1 つのインスタンスを超えてスケーリングする必要がある場合、そのインスタンス全体を複製する比較的単純なプロセスを通じてこれを行うことができます。 アプリケーションを個別のサービスに分離する追加の作業は、アプリケーションの完全なインスタンスをスケーリングする際に最小限の利点を提供します。これはシンプルでコスト効率が高い場合です。
アプリケーションの開発の初期段階では、自然な機能境界がどこにあるか明確に把握できない場合があります。 実行可能な最小限の製品を開発する際に、自然分離はまだ出現していない可能性があります。 これらの条件の一部は一時的な場合があります。 最初にモノリシック アプリケーションを作成し、後でマイクロサービスとして開発およびデプロイする一部の機能を分離します。 その他の条件は、アプリケーションの問題領域に不可欠な場合があります。つまり、アプリケーションが複数のマイクロサービスに分割されることは決してありません。
アプリケーションを多数の個別のプロセスに分離すると、オーバーヘッドも発生します。 機能を異なるプロセスに分離する方が複雑になります。 通信プロトコルはより複雑になります。 メソッド呼び出しの代わりに、サービス間の非同期通信を使用する必要があります。 マイクロサービス アーキテクチャに移行するときは、eShopOnContainers アプリケーションのマイクロサービス バージョンに実装されている構成要素の多くを追加する必要があります。イベント バスの処理、メッセージの回復性と再試行、最終的な整合性などです。
もっと単純な eShopOnWeb 参照アプリケーション では、一体型コンテナーの単一コンテナ使用をサポートしています。 このアプリケーションには、従来の MVC ビュー、Web API、Razor Pages を含む 1 つの Web アプリケーションが含まれています。 必要に応じて、アプリケーションの Blazor ベースの管理コンポーネントを実行できます。そのためには、別の API プロジェクトも実行する必要があります。
docker-compose build
コマンドとdocker-compose up
コマンドを使用して、ソリューション ルートからアプリケーションを起動できます。 このコマンドは、Web プロジェクトのルートにある Dockerfile
を使用して Web インスタンスのコンテナーを構成し、指定されたポートでコンテナーを実行します。 GitHub からこのアプリケーションのソースをダウンロードし、ローカルで実行できます。 このモノリシック アプリケーションでも、コンテナー環境にデプロイする利点があります。
1 つの場合、コンテナー化されたデプロイとは、アプリケーションのすべてのインスタンスが同じ環境で実行されることを意味します。 このアプローチには、早期のテストと開発が行われる開発環境が含まれます。 開発チームは、運用環境に一致するコンテナー化された環境でアプリケーションを実行できます。
さらに、コンテナー化されたアプリケーションは、低コストでスケールアウトされます。 コンテナー環境を使用すると、従来の VM 環境よりも大きなリソース共有が可能になります。
最後に、アプリケーションをコンテナー化すると、ビジネス ロジックとストレージ サーバーが強制的に分離されます。 アプリケーションがスケールアウトされると、複数のコンテナーはすべて 1 つの物理ストレージ メディアに依存します。 このストレージ メディアは、通常、SQL Server データベースを実行する高可用性サーバーです。
Docker のサポート
eShopOnWeb
プロジェクトは .NET 上で実行されます。 そのため、Linux ベースまたは Windows ベースのコンテナーで実行できます。 Docker のデプロイでは、SQL Server に同じホストの種類を使用する必要があることに注意してください。 Linux ベースのコンテナーを使用すると、フットプリントが小さくなり、推奨されます。
Visual Studio 2017 以降を使用して、ソリューション エクスプローラーでプロジェクトを右クリックし、[Add]\(追加\)>を選択することで、既存のアプリケーションに Docker サポートを追加できます。 この手順では、必要なファイルを追加し、それらを使用するようにプロジェクトを変更します。 現在の eShopOnWeb
サンプルには、これらのファイルが既に配置されています。
ソリューション レベルの docker-compose.yml
ファイルには、ビルドするイメージと起動するコンテナーに関する情報が含まれています。 このファイルを使用すると、 docker-compose
コマンドを使用して複数のアプリケーションを同時に起動できます。 この場合は、Web プロジェクトを起動するだけです。 これを使用して、別のデータベース コンテナーなどの依存関係を構成することもできます。
version: '3'
services:
eshopwebmvc:
image: eshopwebmvc
build:
context: .
dockerfile: src/Web/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "5106:5106"
networks:
default:
external:
name: nat
docker-compose.yml
ファイルは、Dockerfile
プロジェクト内のWeb
を参照します。
Dockerfile
を使用して、使用する基本コンテナーと、それに対するアプリケーションの構成方法を指定します。
Web
の Dockerfile
は次のとおりです。
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY *.sln .
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./
ENTRYPOINT ["dotnet", "Web.dll"]
Docker の問題のトラブルシューティング
コンテナー化されたアプリケーションを実行すると、停止するまで実行が続行されます。
docker ps
コマンドを使用して、実行中のコンテナーを表示できます。 実行中のコンテナーを停止するには、 docker stop
コマンドを使用し、コンテナー ID を指定します。
Docker コンテナーの実行は、開発環境で使用しようとする可能性のあるポートにバインドされる可能性があることに注意してください。 実行中の Docker コンテナーと同じポートを使用してアプリケーションを実行またはデバッグしようとすると、サーバーがそのポートにバインドできないことを示すエラーが表示されます。 もう一度、コンテナーを停止すると問題が解決されます。
Visual Studio を使用してアプリケーションに Docker サポートを追加する場合は、その際に Docker Desktop が実行されていることを確認してください。 ウィザードの開始時に Docker Desktop が実行されていない場合、ウィザードは正しく実行されません。 さらに、ウィザードは現在のコンテナーの選択を調べて、適切な Docker サポートを追加します。 Windows コンテナーのサポートを追加する場合は、Windows コンテナーを構成して Docker Desktop を実行している間にウィザードを実行する必要があります。 Linux コンテナーのサポートを追加する場合は、Linux コンテナーを構成して Docker を実行している間にウィザードを実行します。
その他の Web アプリケーションアーキテクチャ スタイル
- Web-Queue-Worker: このアーキテクチャのコア コンポーネントは、クライアント要求を処理する Web フロントエンドと、リソースを集中的に使用するタスク、実行時間の長いワークフロー、またはバッチ ジョブを実行するワーカーです。 Web フロントエンドは、メッセージ キューを介してワーカーと通信します。
- N 層: N 層アーキテクチャでは、アプリケーションが論理層と物理層に分割されます。
- マイクロサービス: マイクロサービス アーキテクチャは、小規模で自律的なサービスのコレクションで構成されます。 各サービスは自己完結型であり、境界付けられたコンテキスト内で 1 つのビジネス機能を実装している必要があります。
リファレンス – 一般的な Web アーキテクチャ
-
クリーン アーキテクチャ
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html -
オニオンアーキテクチャ
https://jeffreypalermo.com/blog/the-onion-architecture-part-1/ -
リポジトリ パターン
https://deviq.com/repository-pattern/ -
クリーン アーキテクチャ ソリューション テンプレート
https://github.com/ardalis/cleanarchitecture -
マイクロサービスの電子書籍の設計
https://aka.ms/MicroservicesEbook -
DDD (Domain-Driven デザイン)
https://learn.microsoft.com/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/
.NET