マイクロサービスの手法を使用してアプリケーションを構築する理由は何ですか

ソフトウェア開発者にとって、アプリケーションを構成要素化することは何も新しいことではありません。 通常、バックエンド ストア、ミドル層ビジネス ロジック、フロントエンド ユーザー インターフェイス (UI) による階層型のアプローチが使用されています。 ここ数年で変化 した ことは、開発者がクラウドのために分散アプリケーションを構築しているということです。

変化するビジネス ニーズには次のようなものがあります。

  • 新しい地理的地域の顧客にアプローチできるように、大規模なサービスを構築して運用する。
  • 顧客の要望にアジャイルに応答する機能を短期間で届ける。
  • リソース利用率を改善し、コストを下げる。

これらのビジネス ニーズが、アプリケーションの構築 方法 に影響します。

マイクロサービスに対する Azure のアプローチの詳細については、「Microservices: An application revolution powered by the cloud. (マイクロサービス: クラウドによって実現されるアプリケーションの革命)」を参照してください。

モノリシックとマイクロサービスのデザイン アプローチの比較

アプリケーションは時間の経過に伴って進化します。 成功したアプリケーションは便利であることで進化します。 失敗したアプリケーションは進化せず、最終的には非推奨となります。 問題は、現在の要件についての知識と、その要件が将来どうなるかということです。 たとえば、企業のある部署のためにレポート アプリケーションを構築するとします。 そのアプリケーションは社内のみで使用され、レポートの保持期間は長くないことがわかっているとします。 選択する手法は、たとえば、数千万の顧客にビデオ コンテンツを配信するサービスを構築する場合とは異なります。

概念実証として何かを外に出すことが推進要因となる場合もあります。 後ほどアプリケーションを再設計できることはわかっています。 利用されることがない過剰なエンジニアリングには意味がありません。 一方、企業がクラウドを構築する場合は、成長と利用が期待されます。 その成長と規模が予想できません。 早期に試作品を作成し、同時に、将来の成功を操作できる道を歩んでいることを確認することが望まれます。 これが、構築、測定、学習、繰り返しからなるリーン スタートアップ手法です。

クライアント/サーバーの時代には、各層で特定の技術を利用する階層型アプリケーションを構築する傾向にありました。 このような手法を表現するために、モノリシック アプリケーションという言葉が登場しました。 インターフェイスが階層間に置かれ、各層内のコンポーネント間ではより密接に結合した設計が使用されるようになりました。 開発者はライブラリにコンパイルするクラスを設計して要素化し、リンクしていくつかの実行可能ファイルや dll を作成していました。

モノリシック設計の手法には長所があります。 多くの場合、モノリシック アプリケーションは設計がより単純になり、プロセス間通信 (IPC) 経由となるためコンポーネント間の呼び出しが速くなります。 また、各自が 1 つの製品をテストするため、人的リソースをより効率よく使用できます。 欠点は、階層化されたレイヤーが密接に結合されることになり、個々のコンポーネントを拡張できないことです。 修正やアップグレードを行う場合、他の開発者がテストを完了するのを待たなければなりません。 アジャイルを実現するのは困難です。

マイクロサービスはこのような欠点に対処しており、前述のビジネス要件に合わせて調整されています。 しかし、利点と欠点の両方がある点は変わりません。 マイクロサービスの利点は、通常は各マイクロサービスで単純なビジネス機能をカプセル化し、それぞれを独立してスケールアウトまたはスケールイン、試験、デプロイ、管理できることです。 マイクロサービス手法の重要な利点の 1 つは、チームが技術主導ではなくビジネス シナリオ主導であることです。 小規模のチームが好みの技術を利用し、顧客シナリオに基づいてマイクロサービスを開発します。

言い換えれば、組織はマイクロサービス アプリケーションを維持する目的で技術を標準化する必要がありません。 サービスを所有する個々のチームは、チームの専門知識に基づくチームに適したアクションや、解決する必要のある問題に最適なアクションを実行できます。 実際には、特定の NoSQL ストアや Web アプリケーション フレームワークなど、一連の推奨技術を用意することが望ましくなります。

マイクロサービスの欠点には、多数の個々のエンティティの管理、複雑化したデプロイの処理とバージョン管理などがあります。 マイクロサービス間のネットワーク トラフィックや、対応するネットワークの待ち時間も増加します。 煩雑で細かなサービスが多いことは、パフォーマンス上の悩みの種です。 依存関係を表示するための支援ツールがなければ、システム全体を見ることが困難になります。

マイクロサービス手法を機能させるには、標準が必要です。標準では、通信方法を指定し、厳密なコントラクトではなく、サービスから必要となるものだけを許容します。 サービスは互いに独立して更新されるため、設計でこうしたつながりをあらかじめ定義することが重要です。 マイクロサービス手法による設計を別の言葉で表現すると "詳細なサービス指向アーキテクチャ (SOA)" となります。

簡単に言うと、マイクロサービスの設計手法とは、サービスの切り離されたフェデレーションであり、各サービスの変更が独立して行われ、合意に基づく通信標準が使用されます。

生成されるクラウド アプリケーションの数が増えるにつれ、アプリケーション全体を独立したシナリオ中心のサービスに分割するこの手法が、長期的には優れた手法であることが明らかになってきています。

アプリケーション開発手法の比較

Service Fabric プラットフォーム アプリケーションの開発

  1. モノリシック アプリケーションにはドメイン固有の機能が含まれ、通常は、Web、ビジネス、データなどの、機能層で分割されます。

  2. 複数のサーバー/仮想マシン/コンテナーでクローンを作成することで、モノリシック アプリケーションを拡張します。

  3. マイクロサービス アプリケーションは機能をより小規模の個別サービスに分割します。

  4. マイクロサービス手法では、各サービスを個別にデプロイすることで拡張し、サーバー/仮想マシン/コンテナーにわたってこれらのサービスのインスタンスを作成します。

マイクロサービス手法による設計はあらゆるプロジェクトに適しているわけではありませんが、前述のビジネスの目的により厳密に合わせることができます。 後でマイクロサービス設計用にコードを書き直す機会があることがわかっている場合は、モノリシック手法を最初から使用する方法が合理的かもしれません。 一般的には、モノリシック アプリケーションを作成し、それを段階的に徐々に分割します。その場合、スケーラビリティまたは迅速性を向上させる必要がある機能領域から始めます。

マイクロサービス手法を使用する場合、多数の小規模サービスでアプリケーションを構成します。 これらのサービスは、マシンのクラスター全体にデプロイされたコンテナーで実行します。 小規模のチームが 1 つのシナリオに重点を置くサービスを開発し、個別にテスト、バージョン管理、デプロイ、拡張するため、アプリケーション全体を進化させることができます。

マイクロサービスとは何か。

マイクロ サービスにはさまざまな定義があります。 ただし、マイクロサービスの次の特性の多くは一般に受け入れられています。

  • 顧客またはビジネス シナリオをカプセル化します。 対処している問題の種類
  • 小規模のエンジニアリング チームが開発します。
  • あらゆるプログラミング言語で記述し、あらゆるフレームワークを使用できます。
  • 個別にバージョン管理、デプロイ、拡張されるコードとステート (任意) で構成されます。
  • 適切に定義されたインターフェイスとプロトコルで他のマイクロサービスと通信します。
  • 場所の解決に使用される一意の名前 (URL) があります。
  • エラーが発生しても、一貫性を維持し、利用できます。

以上の内容をまとめます。

マイクロサービス アプリケーションは、適切に定義されたインターフェイスと標準プロトコルで互いに通信する、個別にバージョン管理され、拡張可能な小規模の顧客中心サービスから構成されます。

あらゆるプログラミング言語で記述し、あらゆるフレームワークを使用できます。

開発者は、技能と作成するサービスのニーズに合わせ、言語やフレームワークを自由に選択できなければなりません。 サービスによっては、C++ の持つパフォーマンス上の利点が他のすべてのものより重視されることがあります。 C# や Java の持つ管理開発の容易さが重要になる場合もあります。 場合によっては、特定のパートナー ライブラリ、データ ストレージ技術、クライアントにサービスを公開する手法が必要になります。

技術を選択したら、サービスの運用管理またはライフサイクル管理と拡張について検討する必要があります。

コードとステートを個別にバージョン管理、デプロイ、および拡張できるようにする

どのようにマイクロサービスを記述するとしても、コードとステート (任意) を個別にデプロイ、アップグレード、スケーリングする必要があります。 これは、技術の選択に関わるため、解決が難しい問題です。 拡張に関しては、コードとステートの両方のパーティショニング (またはシャーディング) 方法を理解するのは困難です。 コードとステートで別々の技術が使用される場合 (今日、一般的になっています)、マイクロサービスのデプロイメント スクリプトは両方を拡張できるものでなければなりません。 また、この違いはアジャイル性と柔軟性にも影響するため、一部のマイクロサービスをアップグレードする場合、それらをすべて一度にアップグレードする必要はありません。

ここで、モノリシックとマイクロサービスのアプローチの比較に戻ってみましょう。 次の図は、ステートを格納するアプローチの違いを示しています。

2 つのアプローチでのステートの格納

Service Fabric プラットフォームのステート ストレージ

左は、1 つのデータベースと固有のテクノロジの層からなるモノリシック手法です。

右はマイクロサービス手法であり、マイクロサービスが相互に接続されています。一般的にステートの対象はマイクロサービスであり、さまざまなテクノロジが利用されます。

モノリシック手法では、通常、1 つのデータベースがアプリケーションに利用されます。 1 つのデータベースを使用する長所はこれが単一の場所であり、デプロイが簡単になることです。 各コンポーネントには、そのステートを格納するテーブルを 1 つ与えることができます。 難点は、チームが厳密にステートを分離しなければならないことです。 そのため、必然的に、既存の顧客テーブルに列を追加し、テーブル間で結合を行い、ストレージ層で依存関係を作ってしまう傾向にあります。 このような場合、個々のコンポーネントを拡張することはできません。

マイクロサービス手法では、各サービスがそのステートを管理し、格納します。 各サービスが、サービスの要求に応じてコードとステートの両方をまとめて拡張する役割を担います。 欠点は、アプリケーション データのビュー (またはクエリ) を作成する必要がある場合、複数のステート ストアにわたりクエリを実行しなければならないということです。 通常、この問題は、マイクロサービスの集合全体でビューを構築する個別のマイクロサービスを用意することで解決されます。 データに対して複数の即席のクエリを実行する必要がある場合、各マイクロサービスでは、オフライン分析のためにデータ ウェアハウス サービスにそのデータを書き込むことを検討する必要があります。

マイクロサービスは、バージョン管理されます。 異なるバージョンのマイクロサービスを組み合わせて実行することができます。 新しいバージョンのマイクロサービスはアップグレード中にエラーを起こす可能性があるので、以前のバージョンにロールバックできるようにする必要があります。 バージョン管理は、異なるユーザーが異なるバージョンのサービスを試す場合の、A/B 試験にも役立ちます。 たとえば、特定の集合の顧客に対してマイクロサービスをアップグレードし、新しい機能をテストしてからより広い範囲でロールアウトするのが一般的です。

明確に定義されたインターフェイスとプロトコルで他のマイクロサービスと通信します

この 10 年間で、サービス指向アーキテクチャの通信パターンに関する情報が数多く公開されています。 一般的に、サービス通信には HTTP と TCP プロトコル、およびシリアル化形式として XML または JSON を適用する REST 手法を使用することになります。 インターフェイスの観点では、Web 設計手法を採用することになります。 ただし、バイナリ プロトコルや独自のデータ形式を使用しても問題はありません。 ただし、これらのプロトコルや形式が公開されないと、ユーザーがマイクロサービスを使用するのに苦労することになります。

場所の解決に使用される一意の名前 (URL) が与えられる

マイクロサービスは、実行される場所に関係なく、アドレス指定できるものでなければなりません。 どのマシンがどのマイクロサービスを実行しているのかわからないようであれば、事態はすぐに悪化する可能性があります。

DNS で特定の URL を特定のマシンに解決するのと同様に、マイクロサービスには、現在地を検出できるようにするための一意の名前が必要です。 マイクロサービスには、実行されているインフラストラクチャから独立した、アドレス指定可能な名前が必要です。 これは、サービスのデプロイ方法と検出方法の間にやり取りがあることを暗示します。サービス レジストリが必要になるためです。 マシンでエラーが発生したときには、レジストリ サービスによってサービスの移動先がわかるようにする必要があります。

エラーが発生しても、一貫性を維持し、利用できます

予期しないエラーの対処は、特に分散システムにおいて、解決が最も難しい問題の 1 つです。 開発者として記述するコードの多くは、例外を処理するものです。 テストの実行中も、大半の時間を例外処理に費やします。 このプロセスは、エラーを処理するコードを記述する以上に複雑です。 マイクロサービスが実行されているマシンでエラーが発生した場合、どうなるでしょうか。 エラーを検出する必要がありますが、それ自体が難しい問題です。 また、マイクロサービスを再起動する必要もあります。

可用性を維持する必要上、マイクロサービスは故障に強くなければならず、別のマシンで再起動できる必要があります。 これらの回復性の要件だけでなく、データが失われてはならず、データの整合性も維持する必要があります。

アプリケーションのアップグレード中にエラーが発生した場合、回復性を達成するのは困難です。 マイクロサービスは、デプロイ システムと連動して、回復すればいいだけではありません。 継続的に新しいバージョンに移行するか、前のバージョンにロールバックして一貫性のある状態を維持できるようにするかを決定する必要があります。 継続的に移行できる十分なマシンがあるかどうかや、前のバージョンのマイクロサービスを復元する方法などの問題を考慮する必要があります。 このような決定を行うために、マイクロサービスは正常性情報を送信する必要があります。

正常性と診断の報告

明白なようでいて見落とされることがよくありますが、マイクロサービスは正常性と診断について報告する必要があります。 それがなければ、運用の観点から正常性に関する洞察を得ることはほとんどできません。 一連の個別サービスで発生する診断イベントの関連付けを行い、マシンのクロック スキューを処理してイベントの発生順序を把握することは困難です。 同意したプロトコルとデータ形式でマイクロサービスと対話するのと同様に、正常性と診断イベントのログ方法も標準化する必要があります。これにより、クエリや表示を行うためのイベント ストアが最終的に確保されます。 マイクロサービス手法では、各チームが 1 つのログ形式に同意することが必要です。 アプリケーション全体の診断イベントを表示する場合に、一貫性のある手法が必要になるためです。

正常性は診断とは異なります。 正常性は、適切なアクションを実行するためにマイクロサービスが現在の状態を報告することです。 典型的な例としては、アップグレードとデプロイメントによる可用性の維持があります。 プロセスのクラッシュやマシンの再起動が発生したため、現在、サービスの状態が正常でないとしても、サービスの動作は引き続き可能な場合があります。 この場合、アップグレードを開始して事態を悪化させてはなりません。 最初に調査するか、マイクロサービスに回復時間を与えることが最良の方法です。 マイクロサービスの正常性イベントにより、得られた十分な情報に基づいて判断することが可能になり、事実上、自己回復サービスを作成できます。

Azure でのマイクロサービスの設計指針

Azure でのマイクロサービスの設計と構築に関するガイダンスについては、Azure アーキテクチャ センターをご覧ください。

マイクロサービス プラットフォームとしての Service Fabric

Azure Service Fabric は、Microsoft が箱入り製品 (通常、モノリシック) の提供からサービスの提供に移行する過程で生まれたものです。 Service Fabric は、Azure SQL Database や Azure Cosmos DB などの大規模なサービスを構築し、運用した経験から形成されました。 プラットフォームは、これを採用するサービスが増えるにつれ、時間の経過と共に発展してきました。 Service Fabric は Azure だけではなく、スタンドアロン Windows Server デプロイメントでも実行できる必要があったということです。

Service Fabric の目的は、サービスの構築と実行に伴う課題を解決し、チームがマイクロサービス手法でビジネス上の問題を解決できるようにインフラストラクチャ リソースを効率的に使用することです。

Service Fabric では、マイクロサービス手法を使ったアプリケーションの構築を支援するために、以下のものが提供されます。

  • 障害が発生したサービスのデプロイ、アップグレード、検出、再起動、サービスの検出、メッセージのルーティング、状態の管理、正常性の監視などを行うシステム サービスを提供するプラットフォーム。
  • コンテナー内で実行するアプリケーションまたはプロセスとして実行されるアプリケーションをデプロイする機能。 Service Fabric は、コンテナーとプロセスのオーケストレーターです。
  • マイクロサービスとしてのアプリケーションの構築を支援する高生産性プログラミング API:ASP.NET Core、Reliable Actors、Reliable Services。 たとえば、正常性や診断に関する情報が得ることができ、また、組み込みの高可用性を利用することができます。

Service Fabric はサービスの構築方法に依存しないため、任意のテクノロジを利用できます。しかし、マイクロサービスの構築を簡単にする組み込みのプログラミング API が提供されています。

既存アプリケーションの Service Fabric への移行

Service Fabric では、既存のコードを再利用し、新しいマイクロサービスを使ってコードを最新化することができます。 アプリケーションの最新化には 5 つのステージがあり、どのステージから始めても、またはどのステージで終えてもかまいません。 以下のステージがあります。

  1. 従来のモノリシック アプリケーションから始めます。
  2. 移行: コンテナーまたはゲスト実行可能ファイルを使って、Service Fabric で既存のコードをホストします。
  3. 最新化: 既存のコンテナー化コードに新しいマイクロサービスを追加します。
  4. イノベーション: ニーズに応じてモノリシック アプリケーションをマイクロサービスに分解します。
  5. アプリケーションをマイクロサービスに変換します。 既存のモノリシック アプリケーションを変換するか、完全に新しいアプリケーションを構築します。

マイクロサービスへの移行

これらのステージは、任意の場所で開始および停止できることを忘れないでください。 次のステージに進む必要はありません。

以下では各ステージの例を示します。

移行
多くの企業が、2 つの理由で既存のモノリシック アプリケーションをコンテナーにリフト アンド シフトしています。

  • 既存ハードウェアの統合と削除またはより高密度でアプリケーションを実行することによるコスト削減。
  • 開発と運用の間の一貫したデプロイ コントラクト。

コストの削減は簡単です。 Microsoft は多くの既存アプリケーションをコンテナー化しており、数百万ドルの節約につながっています。 一貫性のあるデプロイは評価するのが困難ですが同じように重要です。 開発者は自分たちに合ったテクノロジを選択できますが、運用部門はアプリケーションのデプロイと管理に 1 つの手法しか受け入れないでしょう。 これにより、運用部門は、開発者に特定の 1 つのテクノロジだけを選択するよう強制することなく、異なるテクノロジをサポートすることによってもたらされる複雑さを緩和できます。 基本的に、すべてのアプリケーションは自己完結型のデプロイ イメージにコンテナー化されます。

多くの組織はここで終了します。 コンテナーの利点は既に得られており、Service Fabric はデプロイ、アップグレード、バージョン管理、ロールバック、正常性監視などの完全な管理エクスペリエンスを提供しています。

最新化
既存のコンテナー化コードに新しいサービスを追加します。 新しいコードを記述する場合は、マイクロサービスのパスを少し戻ることをお勧めします。 これにより、新しい REST API エンドポイントまたは新しいビジネス ロジックが追加することになるかもしれません。 このようにして、新しいマイクロサービスの構築を開始し、開発してデプロイします。

イノベーション
マイクロサービス手法では、ビジネス ニーズの変化に対応することができます。 このステージで決定するべきことは、モノリシック アプリケーションを複数のサービスに分割する、つまり革新を始める必要があるかどうかということです。 従来の例として、ここではワークフロー キューとして使用されているデータベースが処理のボトルネックになっている場合を示します。 ワークフロー要求の数が増えたら、スケーリングのために作業を分散する必要があります。 スケーリングしない特定のアプリケーションや、頻繁に更新する必要があるアプリケーションについては、マイクロサービスに分割して革新します。

アプリケーションをマイクロサービスに変換する
このステージで、アプリケーションは完全なマイクロサービスで構成される、またはマイクロサービスに分割されるようになります。 ここまで来れば、マイクロサービス化の目的は達成しています。 ここから始めることもできますが、マイクロサービス プラットフォームなしで行うのは多大な投資です。

私のアプリケーションにマイクロサービスは適しているでしょうか。

その可能性はあります。 Microsoft では、ビジネス上の理由からクラウドの構築を開始するチームが増えるにつれ、チームの多くがマイクロサービスと同様の手法を利用する利点を実感しています。 たとえば、Bing では、長年にわたってマイクロサービスが使用されています。 他のチームにとって、マイクロサービス手法は新しいものでした。 チームの主要な得意分野が及ばないところに、解決しなければならない難問があることがわかりました。 そこで Service Fabric がサービス構築技術として注目されました。

Service Fabric の目的は、マイクロサービス アプリケーションの構築の複雑性を減らすことです。複雑性が減れば、多くのコストがかかる再設計を繰り返す必要がなくなります。 そのため、小規模なものから始めて、必要に応じて拡張し、サービスを廃止したり、新しいサービスを追加したりしながら、お客様の利用状況に合わせて進化する手法がとられています。 大部分の開発者にマイクロサービスをよりわかりやすくするために解決する必要がある問題がまだ多く残っていることもわかっています。 その方向に向かう小さなステップとして、コンテナーとアクター プログラミング モデルの例があります。 さらに多くのイノベーションが登場し、マイクロサービスのアプローチが簡単になることを確信しています。

次のステップ