このリファレンス ガイドは、マイクロサービスの設計、構築、デプロイに関する 4 部構成シリーズの第 1 部です。このシリーズでは、マイクロサービス アーキテクチャのさまざまな要素について説明します。このシリーズには、マイクロサービス アーキテクチャ パターンの利点と欠点、およびその適用方法に関する情報が含まれています。
- マイクロサービスの概要(このドキュメント)
- モノリスをマイクロサービスにリファクタリングする
- マイクロサービス設定でのサービス間通信
- マイクロサービス アプリケーションの分散トレース
このシリーズは、モノリシック アプリケーションをマイクロサービス アプリケーションにリファクタリングするための移行を設計して実装するアプリケーション デベロッパーとアーキテクトを対象としています。
モノリシック アプリケーション
モノリシック アプリケーションは、さまざまなモジュールが 1 つのプログラムに結合される単一層ソフトウェア アプリケーションです。たとえば、e コマース アプリケーションを構築する場合、アプリケーションにはオブジェクト指向プログラミング(OOP)の原則に準拠したモジュール式アーキテクチャが必要です。次の図は、e コマース アプリケーションの設定例を示していて、アプリケーションがさまざまなモジュールで構成されています。モノリシック アプリケーションでは、プログラミング言語の構造(Java パッケージなど)とビルド アーティファクト(Java JAR ファイルなど)を組み合わせてモジュールが定義されます。
図 1. プログラミング言語構造の組み合わせを使用する複数のモジュールを備えたモノリシック e コマース アプリケーションの図
図 1 では、e コマース アプリケーションのさまざまなモジュールが、支払い、配達、注文管理のビジネス ロジックに対応しています。これらのモジュールはすべてパッケージ化され、単一の論理実行可能ファイルとしてデプロイされます。実際の形式は、アプリケーションの言語とフレームワークによって異なります。たとえば、多くの Java アプリケーションは JAR ファイルとしてパッケージ化され、Tomcat や Jetty などのアプリケーション サーバーにデプロイされます。同様に、Rails または Node.js アプリケーションは、ディレクトリ階層としてパッケージ化されます。
モノリスのメリット
モノリシック アーキテクチャは、アプリケーションを構築するための従来のソリューションです。アプリケーションにモノリシック設計を採用する利点は次のとおりです。
- Selenium などのツールを使用して、モノリシック アプリケーションのエンドツーエンドのテストを実装できます。
- モノリシック アプリケーションのデプロイが、パッケージ化されたアプリケーションをサーバーにコピーするだけでできます。
- モノリシック アプリケーションのすべてのモジュールがメモリ、容量、リソースを共有するため、ロギング、キャッシュ、セキュリティなど、横断的な問題に単一のソリューションで対応できます。
- モノリシック アプローチでは、モジュールが直接相互を呼び出すことができるため、パフォーマンスが向上します。ただし、マイクロサービスが相互に通信するには、通常、ネットワーク呼び出しが必要です。
モノリスの課題
複雑なモノリスでは、多くの場合、ビルド、デバッグ、論証が次第に困難になります。場合によっては、問題がメリットを上回る場合もあります。
- アプリケーションは通常、時間の経過とともに成長します。モジュールが緊密に結合されていて、大規模で複雑なアプリケーションでは、変更の実装が複雑になることがあります。コードを変更するとシステム全体に影響するため、変更を徹底的に調整する必要があります。変更を調整すると、全体的な開発およびテストプロセスが、マイクロサービス アプリケーションよりもはるかに長くなります。
- 大規模なモノリスを使用して継続的インテグレーションと継続的デプロイ(CI / CD)を実現するのが、複雑になる場合があります。このように複雑になるのは、アプリケーションの一部を更新するために、アプリケーション全体を再デプロイする必要があるためです。また、リグレッションの確認には、アプリケーション全体の広範な手動テストが必要になる可能性があります。
- モノリシック アプリケーションでは、異なるモジュールでリソース要件が競合している場合、スケールが難しくなることがあります。たとえば、1 つのモジュールで CPU 使用率の高い画像処理ロジックを実装する場合です。別のモジュールがインメモリ データベースであるような場合もあります。これらのモジュールはまとめてデプロイされるため、ハードウェアの選択で妥協が必要になります。
- すべてのモジュールが同じプロセス内で実行されるため、メモリリークなどのモジュールのバグにより、システム全体がダウンする可能性があります。
- 新しいフレームワークと言語を採用する場合、モノリシック アプリケーションは、より複雑になります。たとえば、新しいフレームワークを使用するようにアプリケーション全体を書き換えると、そのフレームワークが著しく改善されていても、時間の面でもお金の面でもコストがかかります。
マイクロサービス ベースのアプリケーション
マイクロサービスは通常、一連の個別機能を実装します。マイクロサービスは、それぞれが独自のアーキテクチャとビジネス ロジックを持つミニアプリケーションです。たとえば、支払いゲートウェイやロジスティクスとのサードパーティ統合など、他のマイクロサービスやアプリケーションのクライアントで使用される API が公開されます。
図 1 は、複数のモジュールを備えたモノリシック e コマース アプリケーションを示しています。次の図は、e コマース アプリケーションをマイクロサービスに分割する一例を示しています。
図 2. マイクロサービスによって機能領域が実装された e コマース アプリケーションの図。
図 2 では、専用のマイクロサービスで e コマース アプリケーションの各機能領域が実装されます。各バックエンド サービスは API を公開し、サービスは他のサービスが提供する API を使用します。たとえば、ウェブページをレンダリングするために、UI サービスはチェックアウト サービスなどのサービスを呼び出します。また、サービスでは非同期のメッセージ ベース通信を使用することもあります。サービス間の通信方法の詳細については、このシリーズの 3 番目のマイクロサービス設定でのサービス間通信をご覧ください。
マイクロサービス アーキテクチャ パターンにより、アプリケーションとデータベース間の関係が大幅に変化します。1 つのデータベースを他のサービスと共有するのではなく、各サービスで要件ごとに最適なデータベースを用意することをおすすめします。サービスごとに 1 つのデータベースがある場合、データに対するすべてのリクエストは共有 API ではなくサービス API を経由するため、サービス間の疎結合が発生します。次の図は、各サービスに独自のデータベースがあるマイクロサービス アーキテクチャ パターンを示しています。
図 3. マイクロサービス アーキテクチャの各サービスが独自のデータベースを持つ。
図 3 では、e コマース アプリケーションの注文サービスは、リアルタイム検索機能を持つドキュメント指向のデータベースを使用して適切に機能しています。支払いと配送サービスは、リレーショナル データベースの強力なアトミック性、整合性、独立性、耐久性(ACID)の保証に依存します。
マイクロサービスのメリット
マイクロサービス アーキテクチャ パターンでは、前述のモノリスの課題で説明した複雑さの問題に対処できます。マイクロサービス アーキテクチャには、次のメリットがあります。
- 全体的な機能は同じですが、マイクロサービスを使用して、アプリケーションを管理可能なチャンクやサービスに分割します。各サービスには、RPC またはメッセージ ドリブンの API の形式で明確に定義された境界があります。その結果、個々のサービスで開発時間が短縮され、把握と保守が容易になります。
- 自律型チームは個々のサービスを個別に開発できます。プロダクトの技術的能力ではなく、ビジネス境界を中心にマイクロサービスを編成できます。開発からテスト、デプロイ、メンテナンス、モニタリングに至るまで、割り当てられたソフトウェアのライフサイクル全体にわたって単一の独立したチームを編成できます。
- 独立したマイクロサービス開発プロセスにより、開発者は異なるプログラミング言語で各マイクロサービスを作成し、多言語で記述されたアプリケーションを作成できます。マイクロサービスごとに最も効果的な言語を使用すると、アプリケーションをより迅速に開発し、アプリケーションを最適化してコードの複雑さを軽減し、パフォーマンスと機能を向上させることができます。
- 機能をモノリスから切り離すことにより、独立したチームによるマイクロサービスの独立したリリースが可能になります。独立したリリース サイクルで、チームの開発スピードと製品化までの時間を改善できます。
- マイクロサービス アーキテクチャでは、各サービスを個別にスケールできます。容量と可用性の制約を満たす各サービスのインスタンスを大量にデプロイできます。また、サービスのリソース要件に最も一致するハードウェアを使用することもできます。サービスを個別にスケールすると、システム全体の可用性と信頼性が向上します。
モノリスからマイクロサービス アーキテクチャに移行したほうがよい具体的な事例を以下に示します。
- スケーラビリティ、管理性、アジリティ、配信速度の改善を実装する。
- 新しいビジネス需要に対応するために、大規模なレガシー アプリケーションを最新の言語および技術スタックに段階的に書き換える。
- 横断的ビジネス アプリケーションや横断的サービスを抽出して、複数のチャネルで再利用できるようにする。再利用できるサービスの例としては、支払いサービス、ログイン サービス、暗号化サービス、フライト検索サービス、顧客プロファイル サービス、通知サービスなどがあります。
- 既存のモノリスの特定の機能に目的に特化した言語またはフレームワークを採用する。
マイクロサービスの課題
モノリスと比較して、マイクロサービスには次のような課題があります。
- マイクロサービスの主な課題は、アプリケーションが分散システムであることで生じる複雑さです。デベロッパーは、サービス間通信メカニズムを選択して実装する必要があります。サービスで、アップストリーム サービスの部分的な障害と使用不能性も処理する必要があります。
マイクロサービスのもう一つの課題は、異なるマイクロサービス間でトランザクションを管理する必要があることです(分散トランザクションとも呼ばれます)。複数のビジネス エンティティを更新するビジネス オペレーションは一般的であり、通常、すべてのオペレーションが適用されるか、すべてが失敗するかのアトミックな方法で適用されます。単一のデータベース トランザクションで複数のオペレーションをラップすると、アトミック性が保証されます。
マイクロサービス ベースのアプリケーションでは、ビジネス オペレーションが複数の異なるマイクロサービスに分散される可能性があるため、さまざまなサービスが所有する複数のデータベースを更新する必要があります。障害が発生した場合、さまざまなマイクロサービスの呼び出しの失敗または成功を追跡し、状態をロールバックすることが重要です。最悪のシナリオでは、障害による状態ロールバックが正しく行われない場合、サービス間にデータの不一致が生じる可能性があります。サービス間の分散トランザクションを設定するさまざまな方法については、このシリーズの 3 番目のドキュメント、マイクロサービス設定でのサービス間通信をご覧ください。
マイクロサービス ベースのアプリケーションの包括的なテストは、モノリシック アプリケーションのテストよりも複雑です。たとえば、モノリシック e コマース サービスで注文を処理する機能をテストするには、アイテムを選択し、カートに追加して、チェックアウトします。マイクロサービス ベースのアーキテクチャで同じフローをテストするには、フロントエンド、注文、支払いなどの複数のサービスを呼び出して、テストを実行します。
マイクロサービス ベースのアプリケーションのデプロイは、モノリシック アプリケーションのデプロイよりも複雑です。マイクロサービス アプリケーションは、通常、それぞれに複数のランタイム インスタンスを持つ多数のサービスで構成されます。また、通信する必要がある他のサービスの場所をサービスが検出できるようにするサービス ディスカバリ メカニズムを実装する必要があります。
マイクロサービス アーキテクチャでは、モニタリングとアラートを行うサービスが増えるため、運用のオーバーヘッドが増加します。また、マイクロサービス アーキテクチャでは、サービス間の通信が増えるため、より多くの障害点が生じます。モノリシック アプリケーションを、小規模なアプリケーション サーバー クラスタにデプロイできる場合があります。マイクロサービス ベースのアプリケーションでは、複数の言語や環境でビルド、テスト、デプロイ、実行を行う個別のサービスが多数存在する場合があります。これらのサービスはすべて、フェイルオーバーと復元力のためにクラスタ化する必要があります。マイクロサービス アプリケーションを製品化するには、高品質のモニタリングとオペレーションのインフラストラクチャが必要です。
マイクロサービス アーキテクチャでサービスを分割すると、アプリケーションでより多くの機能を同時に実行できます。ただし、モジュールは独立したサービスとして実行されるため、サービス間のネットワーク呼び出しのためにレスポンス時間にレイテンシが発生します。
すべてのアプリケーションがマイクロサービスに分割できるほどの大きさを持つわけではありません。また、リアルタイムのデータの高速ストリームを処理する必要があるアプリケーションなどで、コンポーネント間の緊密な統合が必要です。サービス間に通信レイヤが追加されると、リアルタイム処理が遅くなる可能性があります。サービス間の通信を事前に考えておくと、サービス境界を明確にマークする際に役立つ分析情報を得ることができます。
マイクロサービス アーキテクチャがアプリケーションに適しているかどうかを判断する際は、次の点を考慮してください。
- マイクロサービスのベスト プラクティスでは、サービスごとにデータベースが必要になります。アプリケーションのデータ モデリングを行う際に、サービスごとのデータベースがアプリケーションに適合するかを確認してください。
- マイクロサービス アーキテクチャを実装する際には、ボトルネックの特定、障害の検出と防止、診断のサポートを行えるように、環境の計測とモニタリングを行う必要があります。
- マイクロサービス アーキテクチャでは、サービスごとに個別のアクセス制御が行われます。セキュリティを確保するには、環境内でも API を使用する外部アプリケーションからも、各サービスへのアクセスを保護する必要があります。
- 同期サービス間通信により、アプリケーションの可用性が低下するのが一般的です。たとえば、e コマース アプリケーションの注文サービスがアップストリームで同期的に他のサービスを呼び出して、そのサービスが利用できない場合は、注文を作成できません。したがって、非同期でメッセージ ベースの通信を実装することをおすすめします。
モノリシック アプリケーションをマイクロサービスに移行するタイミング
すでにモノリスを正常に実行している場合、マイクロサービスを採用するにはチームに大きな投資費用が発生します。マイクロサービスの基本的性質はチームによって実装方法が異なります。エンジニアリング チームには、マイクロサービスのサイズが小さいか、必要なマイクロサービスの数がいくつあるかによってそれぞれ結果が異なります。
マイクロサービスがアプリケーションにとって最適な方法かどうかを判断するために、まず対処したい主なビジネス目標や課題を特定します。目標を達成する、または特定された問題に対処するための、より簡単な方法がある場合もあります。たとえば、アプリケーションをより迅速にスケールアップしたい場合、自動スケーリングの方が効率的かもしれません。本番環境でバグが見つかった場合は、単体テストと継続的インテグレーション(CI)の実装から始めます。
マイクロサービス アプローチが目標を達成する最良の方法であると思われる場合は、まずモノリスから 1 つのサービスを抽出し、それを開発、テスト、本番環境でデプロイします。詳細については、このシリーズの次のドキュメント、モノリスをマイクロサービスにリファクタリングするをご覧ください。1 つのサービスを正常に抽出し、本番環境で実行したら、次のサービスの抽出を開始して、各サイクルから学習を続けます。
マイクロサービス アーキテクチャ パターンでは、システムは個別にデプロイ可能なサービスに分解されます。モノリシック アプリケーションを開発する場合は、大規模なチームを調整する必要があります。このため、ソフトウェアの開発に時間がかかる可能性があります。マイクロサービス アーキテクチャを実装すると、小規模な自律型チームが並行して作業できるようになり、開発を加速できます。
このシリーズの次のドキュメント、モノリスのマイクロサービスをリファクタリングするでは、モノリシック アプリケーションをマイクロサービスにリファクタリングするためのさまざまな戦略について説明します。
次のステップ
- このシリーズの次のドキュメントを読み、マイクロサービスを分解するためのアプリケーション リファクタリング戦略について学習する。
- このシリーズの 3 番目のドキュメントを読み、マイクロサービス設定でのサービス間通信について学習する。
- このシリーズの 4 番目の最後のドキュメントを読み、マイクロサービス間でのリクエストの分散トレースについて学習する。