投稿

MSA(マイクロサービス)とモノリスの違いを今さら整理する

MSA(マイクロサービス)とモノリスの違いを今さら整理する

まとめ

  • MSA = アプリを小さな独立サービス群に分割する設計、対義語はモノリス(1 つの大きなアプリ)
  • 各サービスは独立デプロイ・独立 DB・言語選択自由
  • 障害局所化・チーム分割しやすさが利点、運用の複雑化が欠点
  • 「Rails は MSA に向かない」と言われるのは、1 アプリで全部やる前提で作られているから

モノリスとは

普段の Web アプリ開発で一番多いやつ。1 つのアプリの中にユーザー機能・決済・通知・管理画面を全部詰めて作る。Rails や Django で素直に作ると、まずこの形になる。

[モノリス]
┌─────────────────────────────────┐
│  1 つのアプリ                       │
│  ├ ユーザー機能                     │
│  ├ 決済機能                        │
│  ├ 通知機能                        │
│  └ 管理機能                        │
│  → 1 つの DB / 1 つのデプロイ        │
└─────────────────────────────────┘

これの何が嬉しいかというと、とにかく作るのが速い。ローカル起動も 1 コマンド、デバッグも 1 プロセスで完結する。機能をまたいで関数呼び出しでつなげられるから、トランザクションも素直に張れる。少人数で立ち上げる初期フェーズには圧倒的に向いてる。

MSA とは

これを機能ごとに別アプリへ切り出すのが MSA。

[MSA]
┌────────┐  ┌────────┐  ┌────────┐  ┌────────┐
│ User   │  │ Payment│  │Notify  │  │ Admin  │
│ Service│  │ Service│  │ Service│  │ Service│
│ + DB   │  │ + DB   │  │ + DB   │  │ + DB   │
└────────┘  └────────┘  └────────┘  └────────┘
    ↕           ↕           ↕           ↕
       HTTP / gRPC / メッセージキューで通信

各サービスは独立して動く別アプリ。HTTP や gRPC、メッセージキュー越しに会話する。

MSA の良いところ

  • 独立デプロイできる。User Service だけ直して出す、ができる
  • 言語・DB を選べる。User は Go、Payment は Java、みたいな構成も理屈上は組める
  • 障害が局所化しやすい。Notify が落ちても User の画面は生きてる
  • チーム分割が綺麗にいく。1 チーム 1 サービスにすればコンフリクトが減る

痛いところ

  • 通信が全部ネットワーク越し。遅いし失敗もする。リトライ・タイムアウト・サーキットブレーカーが必須になる
  • トランザクションが分散する。サービスをまたいだ「失敗したら全部戻す」が普通にはできず、Saga パターン等の補償処理が必要
  • 認証・認可・ログ・トレースを横断で設計しないといけない
  • ローカル開発が重い。10 サービス同時起動みたいになる
  • 少人数だとオーバーキル。3 人で 10 サービスは持てない

Rails が MSA に向かないと言われる理由

Rails は「1 アプリで全部やる」設計。autoload で全クラスを起動時にロードし、Active* 系(ActiveRecord / ActiveJob / ActionMailer 等)が同じプロセスに乗る前提で噛み合っている。Rack ミドルウェアスタックや initializer 群もアプリ起動コストとして固定で乗る。

小さなサービスを 10 個 20 個並べる世界だと、1 サービスあたり数百 MB のメモリと起動数秒というオーバーヘッドが効いてくる。サービスの粒度が細かいほど割に合わなくなる。

ただし「MSA で Rails を使ってはいけない」わけではない。1 サービスが業務ドメイン単位(数十 endpoint 規模)なら Rails でも十分回るし、Shopify や GitHub のように Rails の Majestic Monolith を巨大スケールで運用する事例もある。本当に細粒度(数 endpoint × 大量)の世界に行くなら、Sinatra / Roda / Hanami や Go の方が素直、というだけの話。

どう選ぶか

  • まずモノリスで作る。困ってから割る。最初から MSA を狙うと大体こける
  • 困りごとの形が見えてから割る。「デプロイの調整コストが重い」「特定機能だけスケール条件が違う」「チームの境界が明確」みたいな具体の痛みが出てから動く
  • 割る順は外側から。決済や通知のように、外部システム連携が明確で疎結合にしやすい場所から切り出す

個人的には、MSA は「使えるカード」として持っておくくらいで、最初から振りかぶる必要はないと思ってる。モノリスで困った時に、必要な部分だけ切り出すくらいで十分間に合う。

トレンドのタグ