『マイクロサービスアーキテクチャ 第2版』読書メモ

# この本を読むに至った背景
- マイクロサービスについてそろそろ勉強せなあかんと思った
  - なんとなく日々マイクロサービスを運用しているが、このサービスのアーキテクチャがこれで正解なのか、それとも不十分なのかもわからない
  - 自分が日々扱っているアーキテクチャの意義や目的をわかっていないことに危機感を覚えた
  - 新たなサービスの構成をマイクロサービスにするのか、あるいはモノリスにする、といった判断をするために情報を整理しておく必要があると思った

# 本
https://amzn.asia/d/2MVokYr


# 読書メモ
※ 私の私見や感想が多く入っています。きちんと学びたい方は、実際に本を読まれることを強くおすすめします。

# 第一部 基礎
## 1章 マイクロサービスとは
### 1.1 マイクロサービスの概要
* 「マイクロサービス」は、ビジネスドメインを中心にモデル化された、独立してリリース可能なサービスのことである
  * 独立してリリース可能な、ということろが重要っぽい
  * 他のサービスへのアクセスはネットワークを経由する
* マイクロサービスはサービス指向アーキテクチャ（SOA）の一種である
    * [サービス指向アーキテクチャとは何ですか?](https://aws.amazon.com/jp/what-is/service-oriented-architecture/)
    * 一つのシステムを、複数の部品（サービス）の集まりとして捉える考え方のこと
    * AmazonとかTwitterも、利用者から見ると一つのシステムだけど、その裏側では様々な部品の集まりだよね
    * マイクロサービスは、サービス指向アーキテクチャを実現するための一つのアプローチだ
        * ソフトウェア業界は、サービス指向アーキテクチャを実現することで、モノリシックなサービスを開発・運用することの苦しみから開放されようとしてきたが、たいていはうまくいかなかった。それは結局、ITベンダーの口車に載せられ、ノウハウもなく盲目的にSOAを実現しようとしたからだろう。マイクロサービスアーキテクチャは、SOAを実践するための具体的なノウハウとなる。
* 各マイクロサービスの中身はブラックボックスと化している
    * その詳細設計やデータベースさえも、外側からはわからない
    * もっというと、**共有データベースを持つ必要がなくなり**、各マイクロサービスは各自でデータベースを持てば良い。
* マイクロサービスアーキテクチャは、**情報隠蔽の概念**を採用している
    * 細かい情報は外部に後悔せず、最低限の情報だけ開示している
    * 外部インターフェースを介して外部とやりとりしているため、要するに変更の影響が生じる箇所がインターフェースに集中するので、変更しやすい箇所と変更しにくい箇所がわかりやすくなる
        * 逆に言うと、内部の処理を変えまくっても、インターフェースに影響が出ない限り問題ない。
    * 一方で、一つのマイクロサービスを修正したが故に、他のマイクロサービスも修正する必要が生じてしまうと、本来マイクロサービスアーキテクチャが享受したかった恩恵を得られていないということになる
    * **疎結合・高凝集な**サービスを構築することが大事だ

### 1.2 マイクロサービスの重要な概念

#### 1.2.1 独自デプロイ可能性
* 一つのサービスのデプロイが、他のサービスに影響を与えたり受けたりすることなく、行われること
* 作者いわく、最も重要な概念らしい
* 「さらに重要なことは、これが可能である、ということだけではなく、これが実際にシステム内でデプロイを管理する方法である、ということです」
    * これはいまいちよくわからなかった……
    * これ、とは「独自デプロイ可能性」のことなんだけど……
* 独自デプロイ可能性を保証するには、マイクロサービスを**疎結合**にする必要がある
    * 一つのサービスを修正したら、他のサービスも直さないといけない、というのは、この概念に反している
* めっちゃ大事な概念だけど、実現するのはけっこう大変らしい
    * これを実現するためには周辺知識を色々学ばないといけないよ


#### 1.2.2 ビジネスドメインに基づくモデル化
* マイクロサービスどうしの境界を定めるためには、ビジネスドメインに基づいてサービスをモデル化する
    * これにより、新機能のリリースや他サービスとの組み合わせが容易になる
* 一方で、複数サービスに渡ってコードの修正が必要な場合、モノリスなサービスよりも対応が大変になる
    * チームを超えて協議する必要があったり、デプロイ順序を考えたりする必要がある

#### 1.2.3 マイクロサービスごとの状態の所有
* **共有データベースは持たない**
    * あるサービスが、他のサービスのデータを取得したい場合、直接データにアクセスするのではなく、そのもう一つのサービスに「データをよこせ」と要求すべきである
    * マイクロサービスは情報隠蔽の概念を中心に据えているので、隠蔽すべきこととそうでないことは、各サービスに決定させるべき
    * それによって、各サービスは自由に変更できる機能と、あまり変更したくない機能を明確に分離できる
    * 「独立デプロイ可能性を実現したい場合、マイクロサービスに対する後方互換性のない変更を制限する必要があります。上流コンシューマとの互換性を壊すと、上流コンシューマも変更を余儀なくされます」
        * これもよくわからなかったけど……上流コンシューマとは、そのマイクロサービスを「使う側」のことで、マイクロサービスを修正したときに「使う側」も修正を余儀なくされるようなことは避けるべきだ、ということだろうか？
        * 後方互換性のない変更を減らすためにも、外部にさらしている部分(インターフェース)とそうでない部分も明確に分けておく必要がある

#### 1.2.4 サイズ
* 各サービスをどのような大きさにすべきか、について考える。
    * 大きさとは、コード量？ 機能数？
    * でもこれって、会社やチーム規模、対象ドメインによって大きく変わるよね
* サイズについては、最初のうちは考えなくて良い。それより、下記2つを優先的に考えた方が良い。
    * **自分たちのチームは、どれくらいの数のサービスを扱うことができるか？**
        * サービス単体のサイズについて考えるよりも、サービスの数そのものをどれくらいチームが許容できるか。
        * 結局、チームのリソースが潤沢でなければ、サービスを多く管理することはやめて、多少*マイクロ*でないサービス群を扱うようにした方がいいのかもしれない
    * **自分たちが扱うドメインは、どのように境界を定めれば、マイクロサービスの恩恵を十分に受けることができるのか？**

#### 1.2.5 柔軟性
* マイクロサービスアーキテクチャは、既存の課題をまるっと解決してくれるような、夢のアーキテクチャではない
* マイクロサービスだってコストがかかり、そのコストがペイできるような恩恵を得られるかどうかを考えるべきだ
* マイクロサービスアーキテクチャは、やり切るか・やらないか、といった二元論で考える必要はない
    * この取り組みは漸進的に進めることができる
    * コストに見合わなそうと感じたら一旦ストップすればいいし、必要に応じて再開することができる


#### 1.2.6 アーキテクチャと組織の連携
* よくある3層アーキテクチャを例にする
    * [Web3層アーキテクチャってなに？Alibaba Cloud, AWS, Azure, Google Cloud のWeb3層アーキテクチャを比べてみました](https://www.softbank.jp/biz/blog/cloud-technology/articles/202206/web-3-tier-architecture/)
    * システムの構成は、ときに組織やチームの構成を反映していることがある。このweb3層アーキテクチャもそうだ。フロントエンド・バックエンド・データベースでそれぞれチームが分かれる。各チームの責務が、各層の面倒をみることになっている。
    * これが悪い、というわけではないのだが、現代において、リリース頻度や速度を高めたいという欲求が生まれ、また引き継ぎやサイロ([サイロとは](https://www.ntt.com/bizon/glossary/j-s/silo.html))を減らす取り組みが行われている。
    * それを実現するために、チーム構成をアーキテクチャに反映するのではなく、サービスごとのチームを切り分け、さらにはアーキテクチャもその単位で分割する方式が採用されつつある。
    * 旧来のWeb3層アーキテクチャでは、一つの機能を加えるために、分断された3つの層に対して、それぞれ手を加える必要があった。
        * この状態は、**関連技術の凝集度は高いものの、ビジネス機能の凝集度が低い**。
    * 提供するサービスごとにアーキテクチャを分け（=マイクロサービス化）、チームの編成もそれに合わせるようにすれば、各チームは自分たちの責務がマイクロな担当サービスであることを認識し、特定の権限化でそれを扱うようになる。バックエンドだからといって、サーバー側の広範な仕様やコード群の面倒を見なくて済むし、引き継ぎに頭を悩ませることもなくなる。
    * マイクロサービスアーキテクチャを採用することで、組織やチーム構成にも変化をもたらす。

### 1.3 モノリス

* マイクロサービスは、モノリシックアーキテクチャに代わるアーキテクチャアプローチとして語られることが多い
    * （余談だけど、モノリシックを、モノリシックと言い間違えてしまう……）
* マイクロサービスを良く理解するためには、その対称なアーキテクチャとして知られるモノリシックを、まずは理解することが大事
* 本書におけるモノリスとは**デプロイユニット(単位)**を示す
    * デプロイする必要性が生じた場合、サービスすべての機能をまとめてデプロイしなければならないとき、これをモノリスと呼ぶ
    * 単一プロセスモノリス、モジュラーモノリス、分散モノリス……など、モノリスに該当する複数のアーキテクチャが存在する

#### 1.3.1 単一プロセスモノリス
* 単一プロセスとしてデプロイするシステム
    * システムを動かすためのすべてのコードが、この中にプロセスとして詰まっている
* モノリシックサービスというと、これを思い浮かべがち
    * 小規模な組織だと役に立つ
    * 実際の現場では、悲しいことに、この単一プロセスモノリスよりも、もっと複雑になっていることが多い

#### 1.3.2 モジュラーモノリス
* 単一プロセスが別々のモジュールで構成されている、単一プロセスモノリスの一つのパターン
* 各モジュールは個々で動いているものの、このサービスをデプロイするためにはすべてをまとめてデプロイする必要がある
* 並列に作業をこなすことができるので高いパフォーマンスを期待できる
* 例えばShopifyもこのアーキテクチャを採用している
* 課題としては、**データベースを共有している**ため、いつかモノリスを分解するときに問題になる可能性がある。

#### 1.3.3 分散モノリス
* 「分散モノリス」は、複数のサービスから構成されているが、何らかの理由でシステム全体をまとめてデプロイする必要があるシステムのこと
* 「経験上、分散モノリスには、分散システムのあらゆる欠点と単一プロセスモノリスの欠点の両方がありますが、どちらの利点も十分にはありません」
* 情報隠蔽やビジネス機能の凝集といった概念に重きが置かれていない環境にありがち
* やめようね。ここまできたらマイクロサービスにしようね。
* むしろ、自分たちはマイクロサービスだと思っているけど、実態としては分散モノリスになってしまっているパターンが多いのかもしれない


#### 1.3.4 モノリスとデリバリ競合
* 他人（他サービス・他チーム）のデプロイが、他人のサービスに影響を与えてしまうことを**デリバリ競合**と呼ぶ
* マイクロサービスでもこれは起こりうるけど、サービスの境界をしっかり分けることで、この問題を軽減できる

#### 1.3.5 モノリスの利点
* モノリスだって利点がある
* 分散システムにおける落とし穴を回避できるし、それによって開発者による運用がシンプルになる。
* また、モノリス内でのコードの再利用が簡単。それに対して、分散システムはコピーしたり、別ライブラリに切り出したりする必要がある。
* **モノリス = レガシー**ではない
    * むやみやたらに批判するのはやめよう
* 安易にマイクロサービスを選ぶのではなく、マイクロサービスにするべき理由を見つけてから移行しよう

#### 1.4 実現技術
* 待ってました、技術のコーナー
* しかし著者は、「最初にマイクロサービスを使い始めるときには、新技術を数多く採用する必要はないと思っています。実際に、それは逆効果になることすらあります」と言っている。
* マイクロサービスアーキテクチャを推し進めていく中で、課題を認識したときに、その課題を解決する手段として技術に目を向ける


#### 1.4.1 ログ集約と分散トレーシング
* 分散システムを構築すると、管理するプロセスの数が増え、どこで何をやっているのかわからなくなってしまう
* 「**最低限、マイクロサービスアーキテクチャ採用の前提条件として、ログ集約システムの実装を強く勧めます**」
* Jaeger, Lightstep, Honeycombなど
* システムのボトルネックを把握することができる。


#### 1.4.2 コンテナとKubernetes
* ついにコンテナとKubernetesのお話
* でもこれらの採用を急ぐ必要はないよ。
    * マイクロサービスが数個しかないときはメリットを享受できないかも
    * デプロイ管理が煩雑になって悩ましいときに採用を検討しよう

#### 1.4.3 ストリーミング
* マイクロサービス間でデータを共有する方法
* （でもいまいち必要性やユースケースがわからなかった……）
* Apache Kafkaなどのサービスが該当する
    * https://qiita.com/sigmalist/items/5a26ab519cbdf1e07af3

#### 1.4.4 パブリッククラウドとサーバーレス
* AWS, GCP, Azure...
* 最近はFaaSなども注目されてるよね


### 1.5 マイクロサービスの利点
* 改めて、マイクロサービスのメリットを整理する

#### 1.5.1 技術の異種性
* マイクロサービスごとに異なる技術を採用できる
    * 言語、コードレベルのアーキテクチャ、ライブラリなど……
* 新たな技術を積極的に採用することもできる
    * 変更の影響がある程度観測できるからだ。モノリシックだと影響範囲が大きくなって手を出しづらい。
* 既存技術のアップデートも柔軟に対応できる
* ただ、複数技術を採用することのコストもあるよ

#### 1.5.2 堅牢性
* システムのとある一部に障害が発生しても、他の部品（サービス）に影響を与えることはない。
* とはいえ、マイクロサービスを構築することによって生じる、特有の障害も潜んでいるよ
    * このことをよく認識しておかないと、分散サービスを構築したせいで堅牢性が低下してしまうケースが発生してしまうよ

#### 1.5.3 スケーリング
* サービス単位で柔軟にスケーリングできる！
    * クラウドサービスが提供しているスケーリングシステムを活用すれば、より効率的にスケーリングすることができる

#### 1.5.4 デプロイ容易性
* サービスごとに切り離して稼働しているため、各サービスへのデプロイが他に影響を与えることがない。だからどんどん頻繁にデプロイすることができるし、何かあっても迅速にロールバックできる。

#### 1.5.5 組織との連携
* サービスごとにチームを立てることで、必要な人員を最小限に抑え、生産性の最適化を図ることができる
    * 大規模なチームで、責務や担当が曖昧な状態で開発することのデメリットを回避できる


#### 1.5.6 合成可能性
* サービスとサービスを組み合わせることで、新たな価値を発揮することが可能
    * 各サービスごとにインターフェースを持っているので、機能どうしを結合して利用することができる
    * モノリシックなサービスでは、インターフェースの数が限られているので、合成することが難しい






(続く...)

### 試験問題っぽく学びを整理する
※ 粛々とインプットしていくよりも、「これが誰かに尋ねられた場合、自分だったらどう答えるか？」を意識して整理していくと、知識が定着しやすい

#### Q. マイクロサービスアーキテクチャとは、端的にどんなサービスですか？
A. サービス指向アーキテクチャの一種で、ビジネスドメインを中心にモデル化された、独立してリリース可能なサービス構成のことです。

#### Q. 従来のモノリスなサービス構成との違いを教えてください
A. マイクロサービスアーキテクチャでは、各サービスを独立してデプロイすることが可能なので、他サービスに影響を与えることなく機能を更新することができます。

#### Q.
A.