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

# 経緯  
ゲームプログラマです！
といいつつ、ここ何年もインフラ、技術顧問ばかりしています  
その中で特にクライアントさんが大きく間違える事の多いアーキテクチャとして    
モノリシックサービスvsマイクロサービス の勘違いが多い事に気が付きました    
特に最近は、マイクロサービス化での成功事例の記事が多く    
不適切なシステムにマイクロサービスを採用する事例が多いので    
どんな時にマイクロサービスが適しているかを経験から説明します    
    
# モノリシックサービス、マイクロサービスとは    
今回は、モノリシックサービス、モジュラモノリス、マイクロサービス、FaaS に分類してみます    
    
## モノリシックサービス    
1つのサービス    
1つのモジュール    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/68578b13-ed98-171b-b511-6c23841914e3.png)
```
App
  Controller
  View
    Public
    CSS
    Js
  Model
```
    
    
MVCフレームワーク等で普通に使われるアーキテクチャ    
例でいうとModel、View、Controllerの各ディレクトリに全ての機能が入っている   
    
## モジュラモノリス    
1つのサービス  
複数のモジュール  
モノリシックサービスに分類されがち  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/14055662-226e-41dd-c08d-3a113503b5d7.png)
```
App
  Login
    Controller
    View
      Public
      CSS
      Js
    Model

  User
  Login
    Controller
    View
      Public
      CSS
      Js
    Model

  History
  Login
    Controller
    View
      Public
      CSS
      Js
    Model
```    
    
例えば上記のように、App内にドメイン単位で機能を分ける    
    
    
## マイクロサービス    
ドメイン単位、機能単位の複数のサービス    
モノリシックサービスとの間にミニサービスを提唱する人もいるが、今回はマイクロサービス＝ミニサービスで  
ミニサービスより細かく分割したものをマイクロサービスと認識する  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/fdb34cfc-f392-de94-3af4-c8ba434b7d5d.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/6e71a5c8-c338-dca3-0df7-928837c5f20c.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を併用する事で、コストを下げやすい  
  
### 障害耐性  
- モノリシックサービス  
システム全体でみた障害率は低くなりがち  
機能単位でみると、他機能への影響を出しやすい  
- マイクロサービス  
障害が一つの機能に閉じ込められるため、他のサービスは独立して動く可能性    
例：新規登録は出来ないが既存ユーザのログインは出来る、レビューは出来ないが商品購入は可能  
  
  
  
# 総括  
マイクロサービス化はメリットデメリットを考えて選びましょう