モジュール境界
Martin Fowler / James Lewis の “Microservices” を取得して読み、 理解した内容を自分の言葉で書いたもの。本文の引用はしていない。
「どこで切るか」の話。 マイクロサービスの記事だが、 中身は分割一般の判断基準として読める。
どこで切るか
業務の能力で切る。技術の層で切らない
UI / バックエンド / データベースという技術の層で分けると、 1つの機能を変えるのに複数チームをまたぐことになる。
代わりに業務の能力で分ける。各チームがその領域について フルスタックのスキルを持つ形になる。
これは Conway の法則 — システムの構造は組織のコミュニケーション構造を映す — の裏返し。技術の層で組織を分ければ、システムも技術の層で分かれ、依存が交差する。
スケールするリーダーの 「チームに特定の製品ではなく一般的な問題を担当させる」も同じ話。
変化の頻度で分ける
よく変わるものと、安定しているものを分ける。 記事の言い方では「変化のパターンによるモジュール化」。
サービスは置き換え可能な部品として設計する。
切れないなら切らない
境界がまだ見えないなら、まずモノリスで始める。 モジュール性は保ったまま作り、モノリスが問題になってから分割する。
理由は、アーキテクチャの決定の本当の帰結は数年後にしか現れないから。
設計の「モノリス」の項と同じ立場。
分割したときに何が起きるか
複雑性は消えない。部品の内部から、部品同士の接続へ移動するだけ。
| 得るもの | 払うもの |
|---|---|
| 独立してデプロイできる。1つの変更で全体を再デプロイしなくていい | リモート呼び出しはプロセス内呼び出しより高くつく。インターフェイスを粗い粒度にする必要がある |
| チームが自律できる | サービス境界をまたぐリファクタリングは、モノリス内より難しい |
| 技術選択を分散できる | 運用対象が増える |
そして厳しい指摘が1つ。 下手なチームは、モノリスよりマイクロサービスの方が散らかったシステムを作る。
分割を支える前提
切ると決めたなら、これらが揃っていないと成立しない。
賢いエンドポイント、間抜けなパイプ
ドメインロジックはサービス自身に置き、通信基盤は単純に保つ。 ESB のように、ルーティングや変換のロジックを配管側へ寄せない。
分散したデータ管理
各サービスが自分のデータストアを持つ。 中央集権的なデータベースをやめる代わりに、 即時の一貫性ではなく結果整合性を受け入れることになる。
ここは分散システムの領域に接続する。
インフラの自動化
継続的デリバリー、自動テスト、デプロイのパイプラインが必須になる。 デプロイを退屈で再現可能なものにするところまで投資する。
リリースとデプロイの「セルフサービス」「密閉ビルド」がここに当たる。
障害を前提に設計する
サービスは障害を優雅に受け止められなければならない。 Netflix の Simian Army のように、営業時間中に意図的に障害を注入して 回復力と監視の有効性を試す。
分散システムの「壊れるまで負荷をかける」と同じ発想。
プロジェクトではなくプロダクトとして持つ
作って引き渡すのではなく、ライフサイクル全体を通じてチームが持ち続ける。 Amazon の “you build, you run it”。
これが運用を書く側と作る側を分けない、という話になる。
判断の順序
1. 境界が業務の能力として見えているか
見えていないなら、モノリスのままモジュール性を保つ
2. 見えているとして、分割で得るものが
リモート呼び出しのコストと、境界をまたぐリファクタリングの難しさを上回るか
3. 上回るとして、支える前提(自動デプロイ、監視、障害設計)が揃っているか
揃っていないなら、先にそちらを作る