ストラングラーフィグパターン - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

ストラングラーフィグパターン

Intent

strangler fig パターンは、モノリシックアプリケーションをマイクロサービスアーキテクチャに段階的に移行して、変革上のリスクやビジネスの中断を軽減するのに有用です。

導入する理由

モノリシックアプリケーションは、ほとんどの機能を単一のプロセスまたはコンテナ内で提供できるように設計されています。コードは、密結合の状態にあります。そのため、アプリケーションの変更時には、徹底的な再テストを行い、リグレッションの問題を回避しなければなりません。変更は個別にテストできず、サイクル時間にその影響が及びます。アプリケーションが多くの機能で強化されているため、かなりの複雑さによって、メンテナンスにかかる時間や市場投入までの時間が長くなり、結果的に、製品のイノベーションが遅れる可能性があります。

アプリケーションの規模が大きくなると、チームの認知負荷が増大すると同時に、チームの所有権の境界が不明瞭になる可能性があります。負荷に応じて個々の機能をスケーリングすることはできず、ピーク負荷に対応するには、アプリケーション全体をスケーリングしなければなりません。また、システムが古くなると、技術が時代遅れになり、サポートコストが増加する可能性があります。モノリシックなレガシーアプリケーションは、開発時に利用可能だったベストプラクティスに従っており、分散を目的とするものではありません。

モノリシックアプリケーションをマイクロサービスアーキテクチャに移行すると、コンポーネントを小規模化して分割できます。これらのコンポーネントは、スケールやリリースを独立して行え、個々のチームが所有することも可能です。これにより、変更を短期間で行えます。変更をローカライズすると共に、テストとリリースを迅速化できるからです。コンポーネントが疎結合されており、個別にデプロイ可能なため、変更の影響範囲も狭められます。

コードの書き換えやリファクタリングによってモノリスを完全にマイクロサービスアプリケーションに置き換える作業には、非常に労力がかかり、大きなリスクも伴います。ビッグバン方式の移行、つまり、一度の作業によるモノリスの移行は、変革上のリスクやビジネスの中断につながります。また、アプリケーションのリファクタリング中に、新機能を追加することは、非常に困難か、不可能です。

この問題を解決する方法の 1 つは、Martin Fowler 氏が提唱した strangler fig パターンの使用です。このパターンでは、機能を徐々に抽出し、既存システムを中心に新しいアプリケーションを構築することで、マイクロサービスに移行します。モノリスの機能を段階的にマイクロサービスに置き換えて、アプリケーションユーザーが移行済み機能を徐々に利用できるようにします。すべての機能を新しいシステムに移行したら、モノリシックアプリケーションは安全に廃止できます。

適用対象

strangler fig パターンは、次の場合に使用します。

  • モノリシックアプリケーションをマイクロサービスアーキテクチャに徐々に移行する必要がある。

  • モノリスの規模と複雑さを考えると、ビッグバン方式の移行アプローチにはリスクがある。

  • ビジネス上、新機能の追加が必要なため、変革の完了を待つことはできない。

  • 変革中には、エンドユーザーへの影響を最小化する必要がある。

問題点と考慮事項

  • コードベースへのアクセス: strangler fig パターンを実装するには、モノリスアプリケーションのコードベースにアクセスできる必要があります。機能をモノリスから移行した後は、軽微なコード変更を行い、モノリス内に破損防止レイヤーを実装して、呼び出しを新しいマイクロサービスにルーティングしなければなりません。コードベースにアクセスできないと、呼び出しをインターセプトできません。コードベースへのアクセスは、受信リクエストのリダイレクトにも重要となります。なぜなら、プロキシレイヤーが移行済み機能の呼び出しをインターセプトしてマイクロサービスにルーティングできるように、一部のコードリファクタリングが必要になる場合があるからです。

  • 不明瞭なドメイン: ステムの早期分割にはコストがかかる可能性があり、特に、ドメインが明確でない場合にそれが顕著です。また、サービス境界が誤解されかねません。ドメイン駆動型設計 (DDD) はドメインを把握する仕組みを、イベントストーミングはドメインの境界を決定する手法を意味します。

  • マイクロサービスの識別: DDD は、マイクロサービスを識別する主要なツールとして使用でき、マイクロサービスを識別するには、サービスクラス間の自然な分割を特定します。サービスの多くは、独自のデータアクセスオブジェクトを所有しているため、分割が容易であり、関連するビジネスロジックを持つサービスや、依存関係がまったくないか少ないクラスは、マイクロサービスに適しています。モノリスを分解する前にコードをリファクタリングすると、密結合を防ぐことができます。また、コンプライアンス要件、リリース頻度、チームの地理的位置、スケーリングのニーズ、ユースケース主導の技術ニーズ、チームの認知負荷なども考慮する必要があります。

  • 腐敗防止層: 移行プロセス中に、モノリス内の機能がマイクロサービスとして移行済みの機能を呼び出す必要がある場合は、腐敗防止層 (ACL) を実装して、各呼び出しを適切なマイクロサービスにルーティングする必要があります。モノリス内の既存の呼び出し元を切り離し、変更を防ぐために、ACL を、呼び出しを新しいインターフェイスに変換するアダプターまたはファサードとして機能させます。この点については、このガイドの前半にある実装セクションで詳しく説明しています。

  • プロキシレイヤーでの障害: 移行中、プロキシレイヤーでは、モノリシックアプリケーションに送信されるリクエストをインターセプトし、レガシーシステムまたは新しいシステムにルーティングします。しかし、こうしたプロキシレイヤーは、単一障害点やパフォーマンス上のボトルネックになる可能性があります。

  • アプリケーションの複雑さ: strangler fig パターンの利点は、モノリスが大規模な場合に最大化します。完全なリファクタリングがあまり複雑でない小規模アプリケーションでは、移行するよりも、マイクロサービスアーキテクチャ内でアプリケーションを書き換える方が効率的かもしれません。

  • サービスインタラクション: マイクロサービスでは、同期的にも非同期的にも通信を行えます。同期通信が要件の場合は、タイムアウトによって接続またはスレッドプールが消費され、アプリケーションパフォーマンスの問題が発生する可能性がないかどうかを検討してください。発生する場合は、サーキットブレーカーパターンを使用して、長時間に及びかねないオペレーションの失敗がすぐに返るようにします。非同期通信を実現するには、イベントとメッセージングキューを使用します。

  • データ集約: マイクロサービスアーキテクチャのデータは、複数のデータベースに分散されます。データ集約が要件の場合は、フロントエンドで AWS AppSync を使用するか、バックエンドでコマンドクエリ責任分離 (CQRS) パターンを使用できます。

  • データ整合性: マイクロサービスにはデータストアがあり、モノリシックアプリケーションもこのデータを使用する場合があります。データを共有するには、キューとエージェントを使用して、新しいマイクロサービスのデータストアをモノリシックアプリケーションのデータベースと同期すると良いでしょう。ただし、2 つのデータストア間でデータの冗長性と結果整合性が生じる可能性があるため、データレイクなどの長期的なソリューションを確立するまでは、戦術的なソリューションとして扱うことをお勧めします。

実装

strangler fig パターンは、特定の機能を、1 つのコンポーネントにした新しいサービスまたはアプリケーションに置き換える方式で、置き換えは、コンポーネントごとに行います。プロキシレイヤーでは、モノリシックアプリケーションに送信されるリクエストをインターセプトし、レガシーシステムまたは新しいシステムにルーティングします。このレイヤーにより、ユーザーが適切なアプリケーションにルーティングされるため、モノリスの機能を継続しながら、新しいシステムに機能を追加できます。古いシステムの機能が新しいシステムの機能にすべて置き換わったら、旧機能を廃止できます。

高レベルのアーキテクチャ

次の図に示すモノリシックアプリケーションには、ユーザーサービス、カートサービス、アカウントサービスという 3 つのサービスがあります。カートサービスはユーザーサービスに依存しており、アプリケーションではモノリシックリレーショナルデータベースが使用されています。

3 つのサービスがあるモノリシックアプリケーション。

最初のステップでは、ストアフロント UI とモノリシックアプリケーションの間にプロキシレイヤーを追加します。開始時、プロキシでは、すべてのトラフィックがモノリシックアプリケーションにルーティングされます。

モノリシックアプリケーションにプロキシを追加する。

アプリケーションに新しい機能を追加する場合は、既存のモノリスには追加せず、その機能を新しいマイクロサービスとして実装します。ただし、モノリスのバグは引き続き修正し、アプリケーションの安定性を確保します。次の図に示すプロキシレイヤーでは、API URL に基づいて、呼び出しをモノリスまたは新しいマイクロサービスにルーティングしています。

プロキシによって、呼び出しをモノリスまたは新しいマイクロサービスにルーティングする。

腐敗防止層の追加

次のアーキテクチャでは、ユーザーサービスがマイクロサービスに移行済みです。カートサービスはユーザーサービスを呼び出しますが、対象サービスはモノリス内で利用できなくなっています。また、新しく移行したサービスのインターフェイスが、モノリシックアプリケーション内にある以前のインターフェイスと一致しない可能性もあります。こうした変更に対処するには、ACL を実装します。移行プロセス中に、モノリス内の機能がマイクロサービスとして移行済みの機能を呼び出す必要がある場合、ACL によって、呼び出しを新しいインターフェイスに変換し、適切なマイクロサービスにルーティングします。

呼び出しを新しいインターフェイスに変換する ACL を追加する。

ACL は、モノリシックアプリケーション内に、移行済みサービスに固有のクラス (UserServiceFacadeUserServiceAdapter など) として実装できます。また、ACL は、それに依存するサービスをマイクロサービスアーキテクチャにすべて移行した後に廃止する必要があります。

ACL を使用する場合、カートサービスは引き続きモノリス内のユーザーサービスを呼び出し、ユーザーサービスは ACL を介して呼び出しをマイクロサービスにリダイレクトします。カートサービスは、マイクロサービスへの移行を認識せずにユーザーサービスを呼び出す必要があります。リグレッションやビジネスの中断を軽減するには、こうした疎結合が必要です。

データ同期の処理

ベストプラクティスを実装するには、マイクロサービス内に自身のデータを所有する必要があるため、ユーザーサービスでは、そのデータを独自のデータストアに保存します。場合によっては、データをモノリシックデータベースと同期する必要があり、これによって、レポートなどの依存関係を処理すると共に、マイクロサービスに直接アクセスする準備が整っていないダウンストリームアプリケーションに対応します。モノリシックアプリケーションでは、まだマイクロサービスに移行済みでない他の関数やコンポーネントのデータが必要になる場合もあるため、新しいマイクロサービスとモノリスのデータを同期しなければなりません。データを同期するには、次の図に示すように、ユーザーマイクロサービスとモノリシックデータベースの間に同期エージェントを導入すると良いでしょう。これにより、ユーザーマイクロサービスは、データベースが更新されるたびにイベントをキューに送信し、同期エージェントは、キューをリッスンし、モノリシックデータベースを継続的に更新します。そうすることで、モノリシックデータベース内のデータと同期対象データとの間に、結果整合性が確保されます。

同期エージェントを追加する。

別のサービスの移行

カートサービスをモノリシックアプリケーションから移行する際、そのコードを修正し、新しいサービスを直接呼び出すようにします。これにより、ACL ではそれらの呼び出しがルーティングされなくなります。このアーキテクチャを以下に図で示します。

別のサービスを移行する。

次の図は、strangler fig パターンによる移行の最終状態を示しており、すべてのサービスがモノリスから移行済みで、モノリスのスケルトンのみが残っています。履歴データは、個々のサービスで所有されているデータストアに移行できます。ACL は削除可能な状態であり、この段階で、モノリスを廃止する準備が整います。

strangler fig パターンでサービスをすべて移行した後の最終状態。

次の図は、モノリシックアプリケーション廃止後の最終的なアーキテクチャを示しています。個々のマイクロサービスは、リソースベースの URL (http://www.storefront.com/user など) またはアプリケーションの要件に基づいて、独自のドメイン (http://user.storefront.com など) 経由でホストできます。ホスト名とパスを使用して HTTP API をアップストリームコンシューマーに公開する主な方法の詳細については、「API ルーティングパターン」セクションを参照してください。

モノリス廃止後の最終アーキテクチャ。

AWS のサービスを使用した実装

アプリケーションプロキシとしての API Gateway の使用

次の図は、モノリシックアプリケーションの初期状態を示しています。lift-and-shift戦略 AWS を使用して に移行されたと仮定して、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスで実行され、Amazon Relational Database Service (Amazon RDS) データベースを使用しているとします。単純化するために、このアーキテクチャでは、1 つのプライベートサブネットと 1 つのパブリックサブネットがある 1 つの仮想プライベートクラウド (VPC) を使用しているとします。また、マイクロサービスは最初に同じ AWS アカウント内にデプロイすると仮定します。(本番環境のベストプラクティスを実装するには、マルチアカウントアーキテクチャを使用してデプロイの独立性を確保します)。EC2 インスタンスは、パブリックサブネット内にある単一のアベイラビリティーゾーンに存在し、RDS インスタンスは、プライベートサブネット内にある単一のアベイラビリティーゾーンに存在しています。Amazon Simple Storage Service (Amazon S3) には、ウェブサイトの JavaScript、CSS、React ファイルといった、静的アセットを保存します。

モノリシックアプリケーションの初期状態 (strangler fig パターンを使用する場合)。

次のアーキテクチャでは、AWS Migration Hub Refactor Spaces によって、モノリシックアプリケーションの前に Amazon API Gateway をデプロイしています。Refactor Spaces によってアカウント内にリファクタリングインフラストラクチャを構築し、API Gateway を、モノリスへの呼び出しをルーティングするプロキシレイヤーとして機能させます。初期状態では、すべての呼び出しがプロキシレイヤーを介してモノリシックアプリケーションにルーティングされます。前述したとおり、プロキシレイヤーは単一障害点になる可能性がありますが、API Gateway はサーバーレスのマルチ AZ サービスであるため、これをプロキシとして使用すると、リスクが軽減されます。

注記

AWS Migration Hub Refactor Spaces は、2025 年 11 月 7 日現在、新規顧客に公開されていません。に似た機能については AWS Migration Hub Refactor Spaces、「」を参照してくださいAWS Transform

API Gateway を使用した、strangler fig パターンの実装。

ユーザーサービスを Lambda 関数に移行して、Amazon DynamoDB データベースにそのデータを保存します。また、Lambda サービスエンドポイントとデフォルトルートを Refactor Spaces に追加し、API Gateway を自動設定して、呼び出しが Lambda 関数にルーティングされるようにします。

API Gateway を使用した、strangler fig パターンの実装: ルーティングの設定。

次の図では、カートサービスも、モノリスから Lambda 関数に移行済みであり、Refactor Spaces にルートとサービスエンドポイントを追加することで、トラフィックを自動的に Cart Lambda 関数にカットオーバーしています。Lambda 関数のデータストアは、Amazon ElastiCache によって管理され、モノリシックアプリケーションは、Amazon RDS データベースと共に EC2 インスタンスに残っています。

strangler fig パターンを使用して、特定のサービスをモノリスから移行している。

次の図では、最後のサービス (アカウント) が、モノリスから Lambda 関数に移行済みで、このサービスは、元の Amazon RDS データベースを引き続き使用しています。また、新しいアーキテクチャには、データベースを個別に持つ 3 つのマイクロサービスが追加済みで、各サービスは、異なるタイプのデータベースを使用しています。目的別データベースを使用してマイクロサービスの特定のニーズを満たすというこうした概念は、ポリグロット永続性と呼ばれます。Lambda 関数は、ユースケースによって決定される各種プログラミング言語で実装することもできます。リファクタリング中は、Refactor Spaces によって、Lambda に向かうトラフィックのカットオーバーおよびルーティングを自動化します。これにより、ルーティングインフラストラクチャの設計、デプロイ、設定に必要なビルダーの時間を節約できます。

strangler fig パターンを使用して、すべてのサービスをモノリスから移行している。

複数アカウントの使用

前の実装では、モノリシックアプリケーションに、プライベートサブネットとパブリックサブネットがある単一の VPC を使用し、単純化のために、同じ AWS アカウント 内にマイクロサービスをデプロイしました。ただし、マイクロサービスがデプロイの独立性 AWS アカウント のために複数の にデプロイされることがよくある実際のシナリオでは、このようなケースはほとんどありません。また、マルチアカウント構造では、設定によって、モノリスから異なるアカウントの新しいサービスに向かうトラフィックをルーティングしなければなりません。

リファクタリングスペースは、モノリシックアプリケーションから API コールをルーティングするための AWS インフラストラクチャの作成と設定に役立ちます。これを使用すると、アプリケーションリソースの一部として、 AWS アカウント内の API GatewayNetwork Load Balancer、リソースベース AWS Identity and Access Management (IAM) ポリシーをオーケストレーションできます。単一のアカウント AWS アカウント または複数のアカウント間で新しいサービスを外部 HTTP エンドポイントに透過的に追加できます。これらのリソースはすべて 内でオーケストレーション AWS アカウント され、デプロイ後にカスタマイズして設定できます。

次の図に示すように、ユーザーサービスとカートサービスを 2 つの異なるアカウントにデプロイするとします。その場合、Refactor Spaces を使用すると、サービスエンドポイントとルートを設定するだけで済みます。Refactor Spaces により、API Gateway と Lambda の統合に加え Lambda リソースポリシーの作成が自動化されるため、モノリスからサービスを安全にリファクタリングすることに注力できます。

で strangler fig パターンを実装します AWS Migration Hub Refactor Spaces。

Refactor Spaces の使用に関するビデオチュートリアルについては、「Refactor Apps Incrementally with AWS Migration Hub Refactor Spaces」を参照してください。

ワークショップ

ブログの参考情報

関連情報