モノリシックサービスvsマイクロサービス 両方経験した上でのPros/Cons

4748 ワード

経緯

ゲームプログラマです!
といいつつ、ここ何年もインフラ、技術顧問ばかりしています
その中で特にクライアントさんが大きく間違える事の多いアーキテクチャとして
モノリシックサービスvsマイクロサービス の勘違いが多い事に気が付きました
特に最近は、マイクロサービス化での成功事例の記事が多く
不適切なシステムにマイクロサービスを採用する事例が多いので
どんな時にマイクロサービスが適しているかを経験から説明します

モノリシックサービス、マイクロサービスとは

今回は、モノリシックサービス、モジュラモノリス、マイクロサービス、FaaS に分類してみます

モノリシックサービス

1つのサービス
1つのモジュール
image.png

App
  Controller
  View
    Public
    CSS
    Js
  Model

MVCフレームワーク等で普通に使われるアーキテクチャ
例でいうとModel、View、Controllerの各ディレクトリに全ての機能が入っている

モジュラモノリス

1つのサービス
複数のモジュール
モノリシックサービスに分類されがち
image.png

App
  Login
    Controller
    View
      Public
      CSS
      Js
    Model

  User
    Controller
    View
      Public
      CSS
      Js
    Model

  History
    Controller
    View
      Public
      CSS
      Js
    Model

例えば上記のように、App内にドメイン単位で機能を分ける

マイクロサービス

ドメイン単位、機能単位の複数のサービス
モノリシックサービスとの間にミニサービスを提唱する人もいるが、今回はマイクロサービス=ミニサービスで
ミニサービスより細かく分割したものをマイクロサービスと認識する
image.png

App1
  Controller
  View
    Public
    CSS
    Js
  Model

App2
  Controller
  View
    Public
    CSS
    Js
  Model

App3
  Controller
  View
    Public
    CSS
    Js
  Model

ドメイン単位でサービスを複数に分割する
各サービスは別プロセスで実行され、RPCによってデータのやり取りを行う
コンテナで実行する事が多い
DBはサービス毎に独立しており、他のサービスのDBへの直接アクセスは禁止
一つ一つのサービスは小さいため、軽量フレームワークが望ましい

FaaS

関数単位
マイクロサービスより更に小さく、今回はFaaSも含めてマイクロサービスとする
image.png

Function1

Function2

Function3

Function4

Function5

Function6

AWSでいう、Lambdaで実装する
それぞれが1関数(1API)という最小単位で実装される
起動や終了もクラウドサービスが自動管理する
非常に機能が小さいので、フレームワークを使わない事も多い

比較

設計

言語、フレームワーク選択

  • モノリシックサービス
    一つの言語で作る必要がある
    基本的に好きな言語、フレームワークを選択可能
  • マイクロサービス
    機能毎に適したアーキテクチャを選択可能
    得意言語フレームワークの異なる技術者を混ぜやすい
    基本的に軽量フレームワークが使われる
    API通信が多くなるため、GRPCやTCPを扱える言語が好ましい

アーキテクチャ設計

  • モノリシックサービス
    APIも少なく設計が容易
  • マイクロサービス
    APIが多く、DBの分割、整合性・・アーキテクチャ設計が非常に複雑になる

コードの複雑さ

  • モノリシックサービス
    サービスが肥大化するので密結合になりやすい
    モジュラモノリスを適用し、モジュールを分割すれば問題ない
  • マイクロサービス
    サービス毎のコードは小さいのでコードは簡単である
    サービスが機能毎にわかれているので、設計がよければ密結合になりにくい

サービス間の通信方式

  • モノリシックサービス
    同じプロセスなので、インメモリで通信が出来るため、速度や同期などが容易
  • マイクロサービス
    RPC(HTTP、WS、TCP、GraphQL、GRPC)等を使う必要がある
    通信のオーバーヘッド及び同期が難しい

並列

  • モノリシックサービス
    ネイティブスレッド、コルーチン等で並列、並行が可能(マルチプロセスよりパフォーマンスが圧倒的に良い)
    ただし、ネイティブスレッドが使いにくいPythonやRuby、PHP等ではパフォーマンス向上しにくい
  • マイクロサービス
    機能毎に別プロセスなので、スレッドには劣るが並列化される

システム整合性

  • モノリシックサービス
    同じプロセス、同じDBを使うので整合性がとれる
  • マイクロサービス
    サービス毎に別プロセス、別DBを使うので、結果整合性しか保証されない

データストア

  • モノリシックサービス
    複数の機能から同じテーブルを操作可能。DBのロック、トランザクションがかけられる
  • マイクロサービス
    サービス毎に別のDBを使うため、DBのロックやトランザクションがかけられないため、結果整合性しか保証出来ない

セキュリティ

  • マイクロサービス
    ユーザがアクセスしてはならない内部APIが多いためセキュリティリスクが高い
    サービス間の認証や権限等を制御する必要がある

運用

ソース、リソース管理

  • モノリシックサービス
    単一コードなので共通コードの管理などがしやすい
    デプロイ単位がシステム全体になり、テストやデプロイ時間がかかる
    システムのアップデートが遅い
    ある機能の不具合でシステム全体がダウンする可能性
  • マイクロサービス
    リポジトリが複数になり管理しにくい
    デプロイ単位が小さいので、テストやデプロイが速い
    システムのアップデートが機能毎に可能なため速い
    機能毎にバージョンが異なるので、バージョン管理がしにくい

スケーリング

  • モノリシックサービス
    細かいスケーリングが出来ない
  • マイクロサービス
    機能毎に細かくスケーリングが可能(オーケストレーション)

サーバコスト

  • マイクロサービス
    基本的にRPCが増え、プロセス(コンテナ)も増え、コストが高くなりやすい
    細かいスケーリング、設定が可能なので、上手く管理すれば安くなる可能性がある
    特にLambda等のFaaSを併用する事で、コストを下げやすい

障害耐性

  • モノリシックサービス
    システム全体でみた障害率は低くなりがち
    機能単位でみると、他機能への影響を出しやすい
  • マイクロサービス
    障害が一つの機能に閉じ込められるため、他のサービスは独立して動く可能性
    例:新規登録は出来ないが既存ユーザのログインは出来る、レビューは出来ないが商品購入は可能

総括

マイクロサービス化はメリットデメリットを考えて選びましょう