1. この資料について
以前、大規模なWebサービス(レガシーシステム)のリプレイスに関わる機会がありました。そこで得た経験を、機密情報に触れないよう抽象化しつつ、より汎用的に活用できる形で整理してみました。
本稿は、古いコードをリプレイスする際に、どのような前提を置き、論点を整理し、解決策を設計していくかをまとめた、思考実験形式の技術メモです。
2. テーマ
長年運用されたレガシー SaaS を対象に、可用性・スケーラビリティ・変更容易性を高める構造へ移行するためのアプローチを検討する。
※本資料は経験を一般化した思考実験であり、構成や数値は特定の企業・システムの実データではありません。
3. レガシーシステムの概要(リプレイス対象)
- サービス:会員機能を持つコンテンツ配信系 SaaS(2010年以前を想定)
- 全部入りのモノリスで HTML レンダリングと API が未分離。
- 古い言語バージョン+独自フレームワーク、グローバル状態や薄いテストが積み上がっている。
- DB は MySQL(Master+Read Replica)。ストアドプロシージャ等に業務ロジックが埋まりがち。
- memcached はキャッシュ用途(冗長化なし)
- NFS で画像・サムネイルなど大量のメディアファイルを保存
- cron/バッチ等が増殖(メール、サムネ生成、予約投稿、課金同期など)
- 監視はインフラ指標(CPU/メモリ等)程度
アーキテクチャ全体像:

4. 課題
- 本サービスは事業の中核プロダクトであり、継続的な改善が必要で、サービス停止は許容されない。
- 古い言語バージョン+独自フレームワーク等の技術的負債の蓄積で、改善のための変更リスク・コストが増大している。
- コードベースが巨大になり、全体把握や障害時の切り分けが難しい。
5. ゴール設定(到達像)
思考実験としての前提:
今回は技術的な設計論にフォーカスするため、予算・期間などのリソースは現実よりも確保できるという条件を設定し、費用対効果の評価は意図的に除外しています。(費用対効果の観点が入ると、議論が発散すると思ったためです)
信頼性:
- SLO (30日)・エラーバジェット
- ログイン成功率:99.9% (約43分/月の障害を許容)
- 課金成功率:99.9%
- 主要ページの閲覧成功率:99.5% (約3.6時間/月の障害を許容)
- 上記 SLO に紐づく SLI を観測可能にし、運用判断・リリース判断に利用する。
- 障害時対応の標準化を推進する(Runbook など)。
デリバリと運用:
- コンテナオーケストレーションにより、水平スケール/縮退/自己修復等を実現する。
- N% リリース(カナリア)を前提に、入口のルーティング制御(新旧振り分け)とロールバック可能性を要件に含める。
アーキテクチャ刷新:
- SPOF(フェイルオーバーなしのRDB、NFS、キャッシュ等)を段階的に排除。
- ドメイン境界を明確化し、影響範囲の局所化と開発スケーラビリティの向上を目指す。
- レガシーコード刷新計画は別項(7)に詳細を記します。
6. アーキテクチャの更新計画
- モノリス脱却の最初の一歩として、ユーザー・認証/課金/コンテンツ等のドメイン境界を定義する(影響範囲の局所化、スケールと変更容易性の向上が目的)。(注:初期段階では過剰に境界を区切りすぎないこと)
- 将来のクライアント刷新の可能性を考慮し、API を中心にアーキテクチャを設計し、クライアントから利用できる形にする。
- HTML レンダリングは SSR として分離し、SSR 内部でも「HTML 組み立て」と「合成(Compose)」を分けて肥大化(API 以外全部入り)を構造的に抑制することを目指す。
- RDB は HA 構成に移行し、フェイルオーバー前提にする。
- キャッシュは Redis Cluster へ移行し、冗長性を高める。
- cron 中心のバッチは、キュー+ワーカーへ移行し、再試行しやすい仕組みへ転換する。
- NFS は Object Storage へ移行し、CDN 配信を採用。Direct Upload を検討する。
アーキテクチャ全体像:

組織変更:
- プラットフォーム(インフラ)を共通基盤として提供可能な組織構造に転換する(CI/CD、監視、実行環境)
- ドメイン境界でグループ化されたクライアント・バックエンド協力体制を構築する。
- 初期段階では SRE は境界を横断し、全体を横串で見る。SLO 運用・リリース整備等を推進する。
7. レガシーシステム(ソースコード)の刷新計画
7.1. 戦略
対象システムは「全部入りモノリス」「HTMLレンダリングとAPIの未分離」「古い言語バージョン+独自フレームワークに固定」といった特徴があり、改修の影響範囲が読みづらく、変更コストが積み上がっています。一方で、事業の中核プロダクトのためサービス停止や機能開発の停滞は許されません。以上を前提に、ソースコード刷新計画を整理します。
候補となるソースコード刷新の戦略:
- 段階的バージョンアップ(既存コード中心に改修、リファクタリング)
- 新旧モジュール併存型(新機能は新モジュール、旧は段階移行・削除)
- Strangler(新実装を新しいマイクロサービスとして分離、段階切替しつつ旧を撤去)
- 全面リプレイス(作り切って一括切替)
評価軸:
- A. 完遂可能性(最終的に旧コード撤去を完遂できるか。旧コードが残るのは失敗と同じ)
- B. 平行性(刷新中も機能追加・改善を継続できるか)
- C. 期間(完遂までの時間)
| A. 完遂可能性 |
B. 平行性 |
C. 期間 | |
|---|---|---|---|
| 段階的バージョンアップ | ○ | ○〜△ | × |
| 新旧モジュール併存型 | △(old/new が癒着しやすい) | ○〜△(癒着による構造複雑化) | △〜× |
| Strangler | △(永遠の二重構造の危険性) |
○ |
△ |
| 全面リプレイス | ○ | ×(変更停止) | △ |
方針:
本件では「継続的な機能開発」が重要であり、ソースコードの特性(独自フレームワーク等)から漸進的改善が難しいケースだと判断します。予定しているドメイン境界の定義/分割との相性が良いことからも「Strangler(段階的リプレイス)」を基本的な戦略とします。
Strangler の注意点(出口戦略):
Stranglerは「新実装の追加」と「旧実装の撤去」をセットで進めて初めて完遂します。二重構造が固定化されないように、旧削除に一定の作業枠(N%)を確保し、進捗を指標で追う仕組みを必ず設定します。(例:旧経路のトラフィック比率、旧エンドポイント数、旧コード変更量など)
7.2. ドメイン境界の設定
対象は「会員機能を持つコンテンツ配信系 SaaS」を想定します。コードベースが大きい前提のため、影響範囲を小さくし、変更しやすい構造に寄せる目的でドメイン境界を定義します。足がかりとして、以下の3つを最小セットとし、この境界に対応してマイクロサービスを設計します。
- 境界1: コンテンツ領域(コンテンツ管理・配信など)
- 境界2: ユーザー/認証領域
- 境界3: 課金領域
7.3. 優先順位の方針
優先度を決める際の観点として「SPOF排除によるリスク低減」「ユーザー価値/SLOへの寄与」「段階的に進めやすいか」等を考えていますが、本資料では詳細を確定していません。
大枠としては、SLI を観測できる状態と段階リリースの土台を作り、その後に SPOF の解消を進め、最後にドメイン境界の強化(コード刷新)に踏み込む流れが自然かなと考えています。優先度の議論は、実際の制約やリスクを並べて検証を進めることができればと思います。
8. 旧環境から新環境への移行方針
旧環境から新環境への移行は、段階切替とロールバック可能を前提に以下を軸に考えています。
- 互換性の担保:本番ログ等から主要なユースケースを抽出し、影響範囲の広いものから優先する。
- 差分検知:旧の入力を新にも流すことで差分を検知し、出力差分やエラー率を比較して問題箇所を修正する。
- 段階切替とロールバック:N%リリースで段階的に流入を増やし、エラー率の監視や SLI の推移を注視する。
- 性能・負荷検証:本番想定の負荷試験を設計し、基準性能とリソース見積もりを確認する。
9. 最後に、リプレイスの結果と期待される効果
- SLI を整備することで、これまで観測できていなかった問題やボトルネックが見えるようになり、改善の優先度がつけやすくなる。
- SPOF を段階的に排除することで、ログイン・閲覧・課金などの主要 SLO の達成に直結する改善が見込まれる。
- コード刷新は高コスト・ハイリスクなため、開発速度(デプロイ頻度、変更リードタイム等)と KPI(例:有料会員の継続、主要ステップの離脱率)を継続的に観測し、数値で確認しながらリプレイスを完遂する。
以上により、プロダクトの改善を継続しつつ、測定可能な形でリプレイスの成果を示すことを目指す。




