四年間モノリスからサービスを抽出し、その後四年間静かに再マージした。モジュラー モノリスは敗北ではなく、オプションを開いたままにしてデプロイの話を退屈にする 設計の選択だ。この記事は意図的にそれを選ぶ主張で、難しい方法でレッスンを教えた マイグレーションからのレシート付きだ。

抽出の時代

2014年から2018年、私は病院プラットフォーム(AFAQ、HAKEEM)、採用プラットフォーム (Talentera)、他にもいくつかで作業し、会話は常に同じ方向に流れた:「これを サービスに分けるべきだ。」 サービスはコードベースがモダンであることを証明する方法だった。 Kubernetesはインフラチームがモダンであることを証明する方法だった。pyproject.toml ファイルを持つ十数個のリポジトリはエンジニアリングプラクティスがモダンであることを 証明する方法だった。

やった。ほとんどの抽出が出荷された。一部は機能さえした。

誰も大声で言わない部分:それらのサービスを「機能させた」ものの多くは、元の データベースとの密結合を保ったことだった。サービス境界は幻想だった。トランザクション 境界は違った。新しいサービスにまたがって変更を調整しなければならないとき — 週に 約一度起きた。ドメイン境界がサービス境界に合わなかったから — cronジョブ、Slackの 調整、そして希望でやった。

再マージの時代

2020年、Bytroから、パターンが逆転した。もっともらしく見えるサービスに分割されていた イベント駆動のレガシーシステムから始め、一つの展開可能なものに静かに再まとめた。 聴衆によって呼んでいたもの:

  • デザインドキュメントでは「モジュラーモノリス」。
  • エンジニアリングミーティングでは「でかいやつ」。
  • プライベートでは「誰もカンファレンストークを書かない合理的なアーキテクチャ」。

これはダウングレードではなかった。取り戻したもの:

  • 単一デプロイ。 一つのCIパイプライン。一つのロールバック。インシデント中に 推論する一つのバージョンスキュー問題。
  • リファクタリング可能な境界。 モジュールAからモジュールBに関数を移したい? IDEアクションで、RFCではない。
  • 正直なトランザクション。 二つの操作が原子的である必要があれば、できた。 そうでなければ、まだモジュール境界で分けた — ただし買うためのデプロイの話に 原子性保証について嘘をつかなかった。
  • より速いローカル開発。 docker compose upが一つのプロセスを開く。九つではない。
  • より安い観測性。 一つのサービスのトレースは木だ。九つのサービスのトレースは グラフだ — そしてグラフはエッジの半分について嘘をついている。スパンの半分が トレースコンテキストを適切に伝播しなかったから。

マイクロサービスについて誰も言わないこと

マイクロサービスが出荷される理由は組織的であり、技術的ではない。チームが 独立してデプロイできるようにする。それが全ピッチで、良いピッチだ — 実際に デプロイケイデンスが衝突する一つ以上のチームがいれば。

同じステージング環境に同じ日に同じ順序でデプロイする三つのチームがいれば、 デプロイカップリング問題はない。三つのチームと一つのモノリスがあり、それは 機能している配置だ。

私が三社で見た病理はこれだ:

  1. 八人のチームがモノリスを構築する。
  2. フリクションを感じ始める。
  3. 誰かがNetflixがマイクロサービスをどうやっているかの記事を読む。
  4. サービスの抽出に18ヶ月を費やす。
  5. 最後に、八人と14のサービスを持つ。
  6. 各サービスは特に誰にも所有されていない。
  7. すべての変更はまだ調整が必要 — ただし今はサービス境界を超えて、 結果整合性を伴い、分散トレーシングを伴い、「サービスXはダウンしているが サービスYはアップしていて、サービスZは何をすべきか?」というまったく 新しい障害モードを伴う。

ステップ2で感じていたフリクションはサービス境界の問題ではなかった。内部モジュール 境界の問題だった。それらはネットワークを導入せずに修正できる。

モジュラーが実際に意味すること

「モジュラーモノリス」の「モジュラー」は機能する。規律はこういうものだ:

  • 慣習ではなく、ビルドシステムで強制されるモジュール境界。 コンパイル時に ordersbillingからインポートできれば、境界はない。望みがあるだけだ。 言語がサポートするものを使え:Goのinternalパッケージ、Rustのクレート、TypeScriptの プロジェクト参照、Javaのモジュールシステム。一つを選んで強制して、違反でビルドを壊せ。
  • モジュール境界はドメイン境界を反映する。 これが難しい部分だ。最初は正しく できない。二回リファクタして、正しい形が現れる。モノリスの中でそのリファクタリングが 安いことが、それをやるのに正しい場所である正確な理由だ。
  • 境界を越えるものについての契約。 値で、参照ではない。イベントで、メソッド 呼び出しではない。公開型で、内部型ではない。それらが整えば、後でモジュールを サービスに抽出するのは週末の作業だ。それらなしでは、抽出は分散モノリスを生む 18ヶ月のプロジェクトだ。

実際にサービスを切り出す時期

私はアンチサービスではない。数十を抽出した。今やる前に探すシグナルはすべて 組織的または運用的だ — 技術的ではない:

  • 特定のチームが、理論上ではなく今すぐ、異なるケイデンスでデプロイしたい。
  • 特定のワークロードがモノリスが安価に提供できないランタイムまたはスケーリング プロファイルを持つ — 例:CPU集約のMLインファレンスパス。
  • 特定のケイパビリティが異なるコンプライアンスまたはテナント境界を持つ — 例: 独自の監査証跡が必要なPII重いサーフェス。
  • ベンダー統合がサービスとして自然だ — 例:モノリスのデプロイ中も動き続けなければ ならないWebhookレシーバー。

共通点:これらはすべて本物の、名前の付いた、具体的な圧力だ。「モダンになるため」は このリストにないし、永遠にないだろう。

レシート

ここで通常p99の特定の数字や定量的なデプロイ時間の改善を引用するだろう。代わりに、 最も私を説得したことを引用する:

Bytroで、以前過度に断片化されたサービストポロジーを密なモジュラーモノリスに 統合した後、チームのオンコールローテーションが静かになった。 インシデントが 少なくなったからではない — 大まかに同じ数だ。しかし「一つのサービスがページされた」 インシデントは一エンジニア、一ターミナル、一ロールバックの問題だ。「六つのサービスが お互いの状態について混乱している」インシデントは六エンジニアの電話会議の問題で、 そこで失った睡眠は取り戻せない。

オンコールローテーションはアーキテクチャについての真実を語るものだ。ローテーションが 健全なら、アーキテクチャは機能している。ローテーションが民衆税なら、アーキテクチャは 間違っている — ホワイトボードにどんな形で描かれていても。

モダンな部分

静かな部分を認める:2025年と2026年、モノリス + 退屈な技術スタックが最もエキサイティングな ものを出荷するのに選ぶものだ。AI支援開発は、コードベース全体がエージェントの コンテキストウィンドウに収まるときはるかに簡単だ。モジュラーモノリスは収まる。 四つの異なる言語と十六の設定フォーマットを持つ九つのサービスは収まらない。

AIツールを有用にしたければ、読めるコードベースを与えろ。モノリスの2026年の ケースは、思いがけずLLM駆動のエンジニアリングワークフローにとって最速の アーキテクチャだということだ。これは何かの意味で私が書いた最も2026年コードな 一文だ。