Strangler Fig パターン

レガシーシステムを段階的に新システムへ移行する設計パターン

マイクロサービス設計パターン

Strangler Fig パターンとは

Strangler Fig パターンは、Martin Fowler が 2004 年に提唱した、レガシーシステムを段階的に新システムへ置き換える移行戦略である。絞め殺しの木 (strangler fig) は宿主の木の窪みで発芽し、宿主から養分を得ながら地面まで根を伸ばして自立し、やがて宿主が枯れても宿主の形をなぞって残る。この置き換わり方をなぞって、旧システムの機能を 1 つずつ新システムへ移し、最後に旧システムを廃止する。

原典は 2004 年の記事で、当時の題は Strangler Application だった。「絞め殺す」だけが独り歩きして植物の比喩が忘れられることを Fowler 自身が懸念し、後に題を Strangler Fig Application へ改めている (2024 年 8 月に Strangler Fig として全面改稿)。日本語の記事が「ストラングラーパターン」と「ストラングラーフィグパターン」の両方で呼ぶのは、この改題の前後どちらを踏んだかの違いである。

なぜ一括移行ではダメか

一括移行が破綻する原因は工数の見積もりよりも、仕様の確定にある。「旧システムと同じものを新しい技術で作る」は言葉の上では簡単だが、旧システムが実際に何をしているかの細部は誰も把握しておらず、掘り出した挙動の多くは今となっては誰も必要としていないものである。それを忠実に作り直す分だけ、投資が丸ごと無駄になる。

観点ビッグバン (一括)Strangler Fig (段階的)
最初に価値が出る時点全機能が揃うまで出ない移行した機能から順に出る
切り戻しの単位全体をまとめて戻すしかない移行した機能ごとに戻せる
事前に必要な調査旧システムの全挙動次に移す機能の範囲だけ
学習の反映完了後にしか分からない1 機能ごとに次の判断へ反映できる

ビッグバン移行は「全部できるまで何も出せない」状態が続き、途中で頓挫するリスクが高い。Strangler Fig は移行途中でも新旧が共存するため、投資と回収が少しずつ、目に見える形で進む。ただし切り戻しがいつでも効くわけではない。読み取り専用の機能なら振り分けを戻すだけで済むが、新サービス側に書き込みを溜め始めた機能は、旧システムへ戻す前に差分を逆方向へ流し込む段取りが必要になる。

移行の流れ

まず旧モノリスの前段にルーター (API Gateway) を配置し、全トラフィックをモノリスに転送する。次に機能を 1 つずつ新サービスに移行し、ルーターで該当パスを新サービスに振り向ける。最終的にモノリスへのトラフィックがゼロになったら、モノリスを廃止する。

Phase 1: ルーター (API Gateway) を前段に配置
  [クライアント][API Gateway][旧モノリス]

Phase 2: 機能 A を新サービスに移行
  [クライアント][API Gateway] → /api/a → [新サービス A]
                                  → /api/* → [旧モノリス]

Phase 3: 機能 B, C も移行
  [クライアント][API Gateway] → /api/a → [新サービス A]
                                  → /api/b → [新サービス B]
                                  → /api/* → [旧モノリス]

Phase N: 旧モノリスを廃止
  [クライアント][API Gateway][新サービス群]

この図が成立するかどうかは、旧システムに「切り出せる継ぎ目」を見つけられるかで決まる。パスで分けられるのは入口の見た目だけで、その裏で 1 つのトランザクションや 1 つのテーブルを旧コードと共有していれば、パスを振り向けた瞬間に整合性が壊れる。設計の主な仕事は新サービスを書くことではなく、旧システムのどこに継ぎ目を入れれば独立して動かせる単位になるかを探すことである。

そのために、移行が終われば捨てる前提のコード (振り分けルール、新旧のデータ同期、旧システム向けの互換用エンドポイント) を書く必要が出てくる。「どうせ捨てるものに工数を使いたくない」と省略すると、結局は一括移行に戻る。過渡的な足場は段階移行の必要経費として最初から見積もりに入れる。

AWS での実装

API Gateway のパスベースルーティングで新旧を振り分ける。

コンポーネントAWS サービス
ルーターAPI Gateway / CloudFront
新サービスLambda / ECS
旧システムEC2 / オンプレミス
データ同期DynamoDB Streams / CDC

データ同期は、旧システムが RDBMS を持つなら DMS の継続的レプリケーション (CDC) で新サービス側へ流し、新サービスが DynamoDB を使うなら DynamoDB Streams で逆方向へ返す、という組み合わせになる。

CloudFront のオリジングループを使えば、新サービス (プライマリ) がエラーを返したときに旧システム (セカンダリ) へ切り替える構成も組める。ただし条件が 2 つある。フェイルオーバーさせたい HTTP ステータスコードをオリジングループ側で明示的に指定する必要があり (接続失敗は 503、タイムアウトは 504 の指定で拾う)、切り替わるのは GET / HEAD / OPTIONS のときだけである。POST や PUT はフェイルオーバーの対象外なので、更新系 API の退避先として当てにしてはいけない。更新系まで戻せるようにするなら、振り分け自体を切り替える手段 (ルーティング設定やフィーチャーフラグ) を別に用意する。

移行の判断基準

どの機能から移行するかは、ビジネス価値と技術的リスクのバランスで決める。変更頻度が高い機能、障害が多い機能、ビジネス上の優先度が高い機能から着手するのが定石。データベースの分離が難しい機能は後回しにする。

落とし穴

  • データの二重管理: 新旧で同じデータを参照する場合、整合性の維持が難しい。腐敗防止層 (ACL) でデータ変換を挟む
  • 移行の長期化: 「旧システムでも動いているから」と移行が停滞し、新旧の並行運用コストが膨らむ
  • ルーティングの複雑化: パスベースの振り分けルールが増えすぎると管理が困難になる

呼び名と関連戦略

日本語ではストラングラーフィグパターン、ストラングラーパターン、絞め殺しの木パターンなど複数の呼び名で紹介される。レガシー移行の文脈で使われるこのパターンは、新規開発の文脈でモノリスから始めて後から分割するモノリスファースト戦略と対になる関係にあり、「一度に全部を作り替えない」という同じ思想を移行と新規のそれぞれで具体化したものと捉えると位置づけが整理しやすい。

最後に、このパターンは技術だけでは完結しない。旧システムが硬直化したのは、それを生んだ設計判断と組織の進め方がそうだったからである。開発体制と業務側の関わり方を変えないまま新サービス群を作れば、数年後に同じ状態の別のレガシーができる。移行計画には「旧システムの停止日」と並べて、誰がどの機能を持ち続けるかという体制の変更も書いておく。

この記事は役に立ちましたか?

関連用語

関連する記事