精読「マイクロサービスアーキテクチャ 第2版」(第Ⅰ部 基礎 - 第3章 モノリスの分割)
マイクロサービスアーキテクチャ 第2版
マイクロサービスの設計、実装、運用に必要なベストプラクティスや最新技術を解説した、実践的なガイドブックです。これを読めば、マイクロサービスに関してそれっぽい会話もできますよ。
関連記事
目標を持つ
マイクロサービスは、目標ではない。実現しようとする変更を明確にし、マイクロサービスを検討する前に、その最終目標を実現できる最も容易な方法を考える[1]
漸進的な移行
ビックバン書き換えをしても、保証されるのはビックバンだけである (Martin Fowler)
漸進的(インクリメンタル)なアプローチでは、マイクロサービスについて学ぶことができ、何か間違いをしても、その影響を抑えることができる。1つか2つの機能領域を選び、本番環境にデプロイした後にマイクロサービスが最終目的に近づくことができるか評価した方が良い
ほとんどの場合、モノリスは敵ではない
- 「モノリスを持たない」ことにこだわらず、アーキテクチャ変更がもたらす利点を重視するようにする
- モノリスとマイクロサービスが共存する現実を否定せず、ニーズや知識の変化に順応しながら常に進化させ続ける
- ドメインの理解が曖昧なままマイクロサービスを作成するのは危険[2]
まず何を分割すべきか
- マイクロサービスに分解する機能を判断する際には、①抽出の容易さ、②マイクロサービスに抽出する利点という2つの要因のバランスを取ることになる(特に容易さを重視して選ぶといい)
階層による分解
- 抽出したい機能のバックエンドコードと関連データを同時に検討する(但し、後回しにしがちなUIの分解も並行して遅れないように計画を進める)
コードファースト
最も一般的な第一歩であり、短期的な利点がより多く得られる傾向がある[3]
データファースト
この方法はあまり見かけないが、データをきれいに分離できるかどうかはっきりしない状況で役に立つことがある
便利な分解パターン
- 詳しくは「モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド」で説明しているが、ここでは一部の概要を共有
ストラングラーフィグパターン
時間をかけて旧システムを新システムでラップし、新システムが旧システムの機能を漸進的に引き継いでいくプロセス
- 既存システムへの呼び出しをインターセプトし、実装済の機能を持つマイクロサービスにリダイレクトする(まだ残っている機能への呼び出しは、引き続きモノリス自体に送られる)
- 一番の利点は、基盤となるモノリシックアプリケーションに変更を加えず、このパターンを実行できる
並列実行
機能のモノリシック実装と新しいマイクロサービス実装を並列で実行し、同じリクエストで処理して、その結果を比較する
機能トグル
機能のオン/オフや、機能の2つの異なる実装を切り替えるためのメカニズム[4]
データ分解における懸念
パフォーマンス
マイクロサービス化により、データベースの結合処理がアプリケーション層に移行し、パフォーマンス低下や遅延の課題が生じる(キャッシュなどで緩和が可能)
データ完全性
マイクロサービス化でデータベースを分割すると、データの整合性をデータベースに依存できなくなる(論理削除などの対処が必要になる)
[5]
トランザクションデータベースを分割すると、ACIDトランザクションの安全性が失われ、分散トランザクションや新たなメカニズムを導入することで複雑さが増す
ツール
データベースの変更は、状態を持つためリファクタリングツールが不足している(スキーマ変更は差分スクリプトでバージョン管理され、厳密な順序で実行されなければならない)
参考
-
たとえば、ロードバランサの背後にある、既存のモノリシックシステムのコピーをいくつか起動するだけで、複数で時間のかかるマイクロサービスに分解するよりずっと効率的に、システムをスケールさせられる ↩︎
-
サービス境界の解釈が適切ではないことにあとから気づいたりするため ↩︎
-
アプリケーションの抽出はDBからの抽出より簡単、アプリケーションコードをきれいに抽出できないとわかったらDBの分解をせずに済む等 ↩︎
-
HTTPプロキシを使うストラングラーフィグパターンの例では、プロキシ層で機能トグルを実装し、実装の切り替えを簡単に制御できるようにしている ↩︎
-
「商品を渡して、代金を受け取る」のように「ここからここまでワンセット」な処理単位のこと ↩︎
Discussion