【マイクロサービス化の判断基準教えます！ 】マイクロサービス化のすゝめ ①

## はじめに
こんにちは！

エンジニアたるもの既存アプリケーションのマイクロサービス化を検討する時ってあると思うのですよ。
そういった時に本当にそうすべきかどうかの持論があるので展開しようかと思います。
今回は2章に分けて説明します、2章は [gRPC vs HTTP/1 with JSON](https://qiita.com/taisei_otsuka/items/5dc2eb0ff7fe6cea557e) です。
こちらも興味があれば是非ご拝読をお願い致します。m(_ _)m

## そもそも、マイクロサービスとは

構成要素を独立したサービス群に分けて連携させるという、
アプリケーションの開発手法、及びアーキテクチャのことを指します。

教科書的な書き方をしましたが、要するにサービス提供を1個のアプリケーションで行わず、
ビジネスロジック単位でN個のアプリケーションに分割して、それを連結させサービス提供を行うということです。

もっともっとシンプルに一言で言うならばマイクロサービスとは「**アプリケーションのモジュール化**」です。

## マイクロサービスはなぜ採用されるのか

ToC向けの大規模サービスの開発において、従来の([モノリシック](https://en.wikipedia.org/wiki/Monolithic_application)な)開発手法では事業成長が阻害されるからです。

例えば1000行のファイルが100ファイルあるだけで10万行のコード量を超えてしまいます。
Netflix等の大規模サービスになってくると下手すると数百・数千万行を超えている可能性すらあります。

事業成長が求められているサービスであれば継続的に採用人数を増やしていくでしょう、
その中で新入社員が**サービスの影響範囲を数百・数千万行のコードから把握すること**は可能だと思いますでしょうか？

また、**サービスの停止が数千万の利益損失**になる場合、
改修や新規機能のリリースの度に綿密な影響範囲の調査が必要となり、
そこに時間を取られリリースの遅延が発生するということも想像に難くないでしょう。

しかし、**サービスは迅速に成長しなければならない**というジレンマが発生します。
(成長していない間の機会損失も数千万に及ぶ可能性があるからです)

アプリケーションの複雑性によって事業成長が阻害される、
という課題に対するアプローチとしてしばしばマイクロサービスが採用されます。

## マイクロサービスのメリット・デメリット

マイクロサービスの提唱者であるマーティン・ファウラー氏は以下のように述べています。

**メリット**

- Strong Module Boundaries (強固なモジュールの境界)
- Independent Deployment (独立したデプロイ)
- Technology Diversity (技術の多様性)

**デメリット**

- Distribution (分散)
- Eventual Consistency (結果の整合性)
- Operational Complexity (運用の複雑さ)

本記事の目的はメリット・デメリットをつらつら書くことではなく、
マイクロサービスの本質と採用基準を説明するための記事なので、そのすべてを紹介しません。
(似たような記事いっぱいあるのでそっち見てください)

より正確に詳しく知りたい方はマーティン・ファウラー氏の原文をどうぞ。
https://martinfowler.com/articles/microservice-trade-offs.html


## 私的見解なマイクロサービスの本質

マイクロサービスの本質は**システムの複雑性を、「アプリケーションのソースコード」から「アプリケーション間の連携」に移譲すること**だと考えます。
(「複雑なアプリケーションを分割することでシステム全体をシンプルにする」といった記事を見かけますが僕はアレは**嘘**だと思っています)

マーティン・ファウラー氏は以下のように述べています。

> Microservice proponents like to point out that since each service is smaller it's easier to understand.
But the danger is that complexity isn't eliminated, it's merely shifted around to the interconnections between services. 
マイクロサービスの支持者は、各サービスが小さければ小さいほど、その内容を理解するのが簡単になるものだと指摘しがちです。
しかし、ここで問題なのはマイクロサービスになることで複雑さが解消されるわけではなく、単にサービス間の相関に複雑性がシフトしただけということです。


これはどういうことでしょうか？
例えば貴方が関数の中に一行コードを追記したとします。
モノリスなアプリケーションであれば数千万行あるコードの中からその関数の影響範囲を容易に算出出来ないでしょう。

このソースコードの複雑性の課題はマイクロサービスで解消可能です。

### 通信の可視化による影響範囲の把握の容易さ

以下がマイクロサービスでの通信を可視化したサービスマップです。
![scorekeep-gettingstarted-servicemap-after-github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/6a02c731-69e3-c3e7-ecb8-119499d7736d.png)
引用元: https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/aws-xray.html


これであれば通信のログを追うことによって自分の改修したサービスがどのサービスに影響を起こすのか容易に把握することが可能となります。
また、修正したサービス内部の影響範囲を洗い出すのもマイクロサービスではアプリケーション自体が小さいため容易となります。

この恩恵を受けるトレードオフとして、「分散」・「結果の整合性」・「運用の複雑さ」のデメリットが発生します。

### 複雑性をサービスの相関に移譲した為のデメリット

A -> B -> C と連結するマイクロサービスがある日突然エラーを起こしたとします。
エラーのアラートはCサービスから出ているからといって、常にCに不具合があるとは限りません。
AもしくはBの段階で不正なデータが生成されてCサービスに悪影響をもたらしている可能性があります。

これが「分散」されるデメリット、原因究明の「運用の複雑」さ、単一のトランザクションでないためロールバックの難易度が上がるための「結果の整合性」というデメリットが発生します。

## 本記事の読者の大半はマイクロサービスは採用しなくていい

私はマイクロサービス化の検討をシステムのスケールや複雑性に照らし合わせるのではなく、
従業員、ひいては組織・事業のスケールに合わせるべきだと考えます。

具体的に強気な言及をしますが、
- 大規模トラフィックではない
- 従業員(開発者)が増えていない・増える予定がない
- ToCサービスではない
- 処理を共通化出来る複数のサービスを持っていない・リリース予定がない
上記のような会社はマイクロサービスを採用せずモノリスでサービス開発することを強くおすすめします。

ToC向けの複数サービスを構築する予定のベンチャーや、
既に大規模トラフィックを獲得している自社サービスの会社はマイクロサービス化の検討の余地ありだと思います。

## 最後に
マイクロサービス化にするも、しないもどちらも「決断」だと思います。
この記事が自社の採用・事業計画と照らし合わせてどうすべきか考えるきっかけになれば幸いです。

ここまでご拝読ありがとうございました。

次回: [HTTP/1 JSON API](https://qiita.com/taisei_otsuka/items/5dc2eb0ff7fe6cea557e) 死す

## 採用PR

大規模サイトのでマイクロサービス構築に興味がある、もしくはチャレンジしてみたいといったお気持ちの方は是非是非一緒に働きましょう！

もちろん、マイクロサービスに興味がない方でも問題ないのでご気軽に応募ください♪

https://hrmos.co/pages/eisys/jobs/0AAA002

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/2000f749-3e82-7a47-b1c4-4444e237f79c.png" width=45%>