Microservices の勉強ノート その一

# なぜ Microservices に興味を湧いたか
　この1－2年で、K8s やコンテナを勉強して、すごく技術も面白くて、Declarative（宣言型）構成のコンセプトもかなり運用に役立ちそうと思っています。ただ、K8s はよく基盤管理者より、開発者に対してメリットが大きいと言われていますが、その「大きい」メリットとの何ぞやと疑問を抱え続けています。
　さらに K8S はよくアジャイル開発や DevOps などのキーワードともよく一緒に語られますが、その関連性は？との疑問もあります。私の理解ですと、別に VM ベースでもアジャイル開発をやり、DevOps を実践できるし、実際にそうやっている企業もあったりします。そこからわざわざ K8S にシフトするメリットは何なんでしょうかとも疑問がります。
　そこから調べていくと、Microservices というキーワードと出会って、アジャイルや DevOps と言った開発手法とは別次元で、アプリのアーキテクチャの視点から、K8S とコンテナの必要性を説明できると気づいて、興味が湧いてきました。

# Microservice 初心者の私の勉強ルート
　諸々調べると、まずは Microservices の総論を把握しといた方がいいと思って、下記の Blog にたどり着きました。
[Microservice](https://martinfowler.com/articles/microservices.html)
　そこから、より詳細な各論について、[O'reilly Building Microservices](https://samnewman.io/books/building_microservices/) を読んでいこうと思います。
　さらに、より実践的な部分に関しては Microservices アーキテクチャを商用に採用した [Netflix の TechBlog](https://netflixtechblog.com/) を読んでみても面白いかと思ます。

# Microservices の総論
#### What is Microservices
　Microservices は単一のアプリを複数の小さい Services で構成するアーキテクチャです。Service というのは各々独立するプロセスのことです。

#### Microservice vs Monolithic
　従来の Monolithic アプリの中にも複数な Function や Method が存在しますが、Function の間は基本 Function Call の形で値を伝達したり、インターアクションしたりします。一方で、Microservices の Service 間は HTTP resource API などの Lightweight Mechanism で通信します。
　Blog を読んで、**Decoupling** という言葉が浮かんできました。プログラムを書く時も、コードの再利用性を上げ、再構築の影響範囲を下げるために、機能ごとに Function や Class に分けて行くのは常識です。さらに、共通機能の部分をライブラリと定義したりするのもごく普通の話です。Decoupling することによって、機能ごとに単独でコンパイルができて、テストや Bug Fix がかなりやりやすくなっています。
　Microservice のコンセプトは Decoupling と似てる部分がかなりあります。機能ごとにService を作り、開発スコープを限定することによって、開発難易度をさげ、運用性をあげます。
　ただ、それだけだったら、ライブラリを使いまくればいいんじゃないかとも思います。でも Blog をさらに読んでいくと、**ライブラリが提供できないメリットも Microservice が具備します。**


#### Microservice のアドバンテージ
1. **機能ごとに言語やツールの選択自由**
　Java/C/Python 様々の言語が増えてきた中、プロジェクトを始める際に、どの言語にすればよいのかがきっとアーキテクトの悩みポイントになります。チームのスキルセット、必要なツール類との相性、ライブラリの充実度、パフォーマンスと運用性のバランスなどなどの要素がある中、最適の一つを選び出すのは至難の業ですが、Monolithic の場合、ライブラリの依存性があるため、異なる言語を使うのはなかなかハードルが高いです。
　ここでいう多言語は MVC モデルの中、フロントエンドが JavaScript でバックエンドが Java と言うような括りではなく、同じバックエンドの中でも、機能ごとに言語を変えられるのかが議題です。
　Microservices の場合、Services 間は API で接続するため、言語の縛りがなくなり、規定された API に従えば、例え全然異なる言語の Services でも Co-work できます。

1. **機能ごとのスケーラビリティ**
　Monolithic の場合、アプリケーションの中に複数の機能が入って、スケールアウトする際にもアプリケーションのインスタンス単位で増やしていきます。そうなる、すべての機能がなからず一緒に増減しなければいけないです。
　Microservice の場合、機能ごとに Service は独立するため、必要のパーツだけを必要の数に増減すれば済みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385161/8fdc4fd1-1181-fd46-becf-5b5b9b94941e.png)
　上図の出典：https://martinfowler.com/articles/microservices.html
　EC サイトを例とすると、商品展示ページ、カート、決済は一連のプロセスになりますが、会員情報管理は全く別のプロセスになるので、二者はスケールに対する要件は明らかに異なってきます。さらに深堀リすると、商品展示ページ、カート、決済の一連の動きでも、展示ページをパラパラ見るだけのお客さん（セッション）はきっとカートに入れて最後の決済まで行くお客さん（セッション）より多いと思います。なので、この一連のプロセスの中でも処理能力に対する要件が変わってきます（特にキャンペーン時とか）。
　したがって、機能ごとに細分化し、必要に応じてスケールするニーズは確かにあります。

1. **機能ごとデプロイ先の選択自由**
　Monolithic アプリはすべての機能がパッケージングされるため、1か所にまとめてデプロイするしかできません。これは従来の DC 中心となるアーキなら問題がなく、各 DC にインスタンスをデプロイすればよいでした。
　ただ、Edge Computing というキーワードに徐々に注目度が集まっている今では、データのソースに近いところにコンプティングリソースを配置するとのアーキをどう活用すればよいかもアプリにとって課題になってきます。
　Edge Computing と Microservice の関係ですが、Microservice が基礎であり、Edge Computing はその基礎のメリットを最大限に生かすための応用になると私が思います。単純にコンピュータをばら撒いて、各地にレガシーな Monolithic アプリをデプロイするのはほぼ無意味です。なぜならば、Edge Computing の本来の目的として、重いデータ伝送を省いて、ローカルで処理を行い、よりよいリスポンスタイムを提供しながら帯域の節約を実現します。ただ、それだけであれば、もう前クラウド時代でやっているローカルシステムをデプロイしまくればよいのではないかとなります。なので、Edge Computing が実現すべきアーキとして、Local Domain (Edge) のデータ処理と Global Domain (cloud) の集約処理の結合になるかと思います。例として、画像識別のシステムはカメラの近くに識別のプロセスを完結しながら、抽出されたデータを Cloud に集約し、モデルの継続トレーニングを行うイメージを持っています。
　そこで、Microservice アーキはこのような 中央 Cloud + 分散 Edge の環境でも、容易に異なるデプロイ先にそれぞれの機能をデプロイして行けます。

# Microservices の課題
　諸々 Microservices のよいところを語りましたが、ベネフィットを得るために、必ずペイが必要です。Microservices を実現するために、諸々考えなければいけない要素があります。
1. **Services の粒度**
　まず、一番真っ先に出てくる質問として、**どの粒度で Service を分割よいか？**
明らかにプログラムの Method / Class ごとに分割すると、Service が多すぎになります。Miscroservices を実践している企業の中でも、Service の大きさがバラバラになり、定量的な標準がないです。結論として、マネージできるレベルでよいです。ここで実践の経験値が貴重になってきます。
　そして、もう一つ面白い理論があります。Amazon が提唱している Two Pizza Team 理論として、1つのサービスを開発運用しているチームの規模は2枚のピザを取り分けれる人数までとすべきです。いわゆる、5－6人まで1チームとした方がいいです。
　この話題に関して、標準回答がないので、継続的な実践とケーススタディーが必要です。

# 次回以降
　ここまで書いて、まだ K8s 関連の技術が登場しないですが、Miscroservice に関する課題がいっぱい残っています。
1. **Services Discovery & LB**
　分割されている Services はお互いどう知り合って、通信しているのか？**（Service Mesh）**

1. **Services 間の通信効率**
　Monolithic の場合、Method 間の通信はメモリ上で完結するので、大したことないですが、HTTP API になってしまうと、性能や遅延とか大丈夫か？**（gRPC）**

1. **Service API の管理**
　Service ごとにいっぱい API を定義すると、だれが何のAPIをもって、どう使えばよいかってどう管理すればよいか？**（API Gateway）**

1. **Service の Lifecycle Management**
　Service が数多くなってきたら、そのデプロイ、冗長、アップデートはどう実現すればよいか？**（Kubernetes）**

1. **Service の 監視**
　Service が数多くなってきたら、それぞれの Service のパフォーマンス監視はどう実現すればよいか？**（Datadog）**

それぞれの課題とその対策について勉強し、次回以降書いていきたいと思います。