マイクロサービスアーキテクチャ【まとめ】 

#はじめに
+ Sam Newmanのマイクロサービスアーキテクチャを読む。
+ 読むのは２回目、改めて読みながらポイントや自分自身の気づきをまとめておく。
+ 本書に記載のない言葉でも関連していると思うものは調べて記載しておく。
+ まずは重要な要素の多い１章のみを対象とする。


####更新履歴
+ 2019.12.4　２章追記
+ 2020.1.24　３章追記

#１章　マイクロサービス

##ヘキサゴナルアーキテクチャ
アプリケーションとドメインを中心に据え、プロトコルやDB、ストレージなどのインフラはポート＆アダプターで接続する。
⇒ドメイン・セントラルな考え方であると理解。

##システム大規模化の問題とは？
+ 変更の必要な個所が分かりづらい
大きなシステムほど調査に時間がかかるし、変更するとテスト工数が大幅に増えてしまうというのはよくある事実

+ 似たような機能が散在し、バグの修正や実装が困難になる
チーム別に類似コードが実装されており、影響調査依頼などで横展開されるが、担当者の前提知識によっては見逃されてしまうリスクがある。

+ 対策にはコードの凝集性がポイントである
同じ役割のコードはまとめておこうという考え方。
気になるのは、組織分割と役割分割は必ずしも一致しないこと。
現場では共有ライブラリ、モジュールの考え方がすぐに復活してしまうのが怖い。

##単一責任の原則
マイクロサービスでも重要な概念である。

> 変更する理由が同じものは集める、変更する理由が違うものは分ける


##マイクロサービスのアプローチは？
サービスの境界をビジネスの境界に合わせる。
⇒そもそものビジネス境界の定義が現場ではとても難しい（業種等によるだろうが）
⇒事務所管で分ける方法もあるが、事務処理自体も便宜的に振り分けられているものも多く、ビジネスとしての境界とは少し違う場合がある（事務所管は別だが、同じところを見ている、つついているといった状況）

##マイクロサービスの最適なサイズとは？
+ ２週間で書き直せるもの（Jon Eaves）
+ 十分に小さく、ちょうどいい大きさであること
    + 小ささはわからずとも、大きすぎるということは容易に理解できるだろう
+ サービスがチーム構造とどの程度一致しているかも重要（組織面）
+ 注意すべきは、サービスが小さいほど、マイクロサービスアーキテクチャの利点と欠点が最大化されること

##【重要】自律性の黄金律
+ 他は何も変更せずに、単独でサービスの変更やデプロイを行えるかどうか。

##マイクロサービスの利点とは？

###①技術異質性
+ サービスごとに異なる技術を使うことができる。

+ 運用を考えると、いろんな技術を使えないのでは？
    + 確かに、NetflixやTwitterではJavaベースで開発している。
    + かといって、必ずしも全て同じということではない。
    + マイクロサービス化することで新技術適用のリスクを抑えることはできる（チャレンジャブルになれる）。
    + 進化的アーキテクチャを実現しやすい。

###②回復性（レジリエンス）
+ サービス境界は明確な隔壁になる
    + 障害が連鎖しないようにする隔壁が重要な考え方になる
    + 隔壁があれば問題を分離し、残りの部分は機能し続けることができる

###③スケーリング
+ 必要な部分だけをスケールさせることができる
    + モノリシックでは、必要な部分だけでなく全体をスケールさせる必要がある

###④デプロイの容易性
+ モノリシックなアプリケーションは全体をデプロイする必要がある
+ マイクロサービスはサービス単位に独立してデプロイできる
+ 問題の特定、ロールバックが迅速に対応可能

###⑤組織面の一致
+ 大規模なコードベースは問題が起きやすい
+ 小規模チームの方が生産性が高い傾向にある
+ マイクロサービスはコードベースを組織に合わせやすい

###⑥合成可能性
+ モノリシックアプリケーションでは外部からの入り口は粒度のあらいものがひとつある
+ マイクロサービスでは、状況の変化に応じて組み立てなおせるようにできる（これを合成可能性といっているようだ）
+ 実際、顧客チャネルとしてはWeb、ネイティブアプリケーション、モバイルWeb、タブレットアプリ、ウェアラブルなど多くのものが考えられる

###⑦交換可能にするための最適化
+ レガシーシステムでは古いプログラムが古いプラットフォーム上で動いている
+ これに手をつけない、つけたくない理由は、大きすぎるゆえにリスクがあるため
+ 個々のサービスサイズが小さければ、交換がしやすくなる

##サービス指向アーキテクチャ（SOA）
+ SOAでは、その考え方を適切に実現する方法について、十分な合意がされていなかった
+ また、説明不足を原因として、多くの落とし穴が生じてしまった

##マイクロサービス以外の分解テクニック

###共有ライブラリ
+ ごく標準的な分解テクニック
+ メリット
    + ライブラリを中心に組織化できる。
+ デメリット
    + 技術的多様性がない、通常は同じ言語かプラットフォームになる。
    + 独立してスケールさせることはできない。　　など

###モジュール
+ モジュールは接合部分が標準化・規格化されているものをいう。
+ 言語によってはモジュールのライフサイクル管理が可能だが、すぐに他のコードと密結合になってしまう。

##銀の弾丸などない
魔法のように、すぐに役に立ちプログラマの生産性を倍増させるような技術や実践はない。

#２章　進化的アーキテクト
※ストレートな話が少ないので、短めにまとめておく。

##システムアーキテクトはアーキテクト（建築士）とは異なる
+ 建築士は数千年の知識体系があるが、我々はそうではない。
    + どのようなものが優れているかは、実際ほとんどわかっていない。
+ システムアーキテクトを再定義する必要がある。
    + すべてを予測することはできないため、変化を許容する。
    + 変更が許容できる計画を立て、区画整理を行う。
    + 区画間で起こることは心配し、区画内で起こることは寛容になるべき（チームの自律性を最大化する）。

##進化的アーキテクトの責務
+ ビジョン
要求をシステムで実現するための技術ビジョン（方針）を明確にする。

+ 共感
顧客や同僚と共感しあい、互いの理解を深める。

+ 協調
ビジョンの定義、改良、実行を同僚らと協調して行う。

+ 適応性
要求に応じて技術ビジョンを変更する。

+ 自律性
チームに対する標準化（制約）と自律性のバランスを取る。

+ ガバナンス
実装を技術ビジョンに合わせるためのガバナンスとる。


#３章　サービスのモデル化方法
##優れたサービスにするポイント
###疎結合
+ マイクロサービスの本質は、**あるサービスを変更しても別のサービスの変更が必要ないこと**。（とても重要！）
+ 連携するサービスについては、必要最低限のことしか把握しない。（それでよい、そうであるべき）

###高凝集性
+ 関連する振る舞いはまとめ、そうでないものは別にする。
+ 振る舞いを変更する場合、１箇所で変更でき、素早くリリースできるようになる。
+ そうでない場合、多くのサービスを同時に開発するため遅くなり、それをリリースするリスクが高くなる。

##境界づけられたコンテキスト
+ Bounded Context, BC, コンテキスト境界、境界コンテキスト
+ Eric Evans著より。
+ コンテキストには、外部と通信する必要のないもの（**隠れモデル**）と、外部と共有すべきもの（**共有モデル**）がある。
+ これらを整理することで、「境界付けられたコンテキスト」が明らかになる。

※コンテキストの単位は、例えば「倉庫」と「経理」。倉庫の隠れモデルは棚や注文のピッキングがある。共有モデルは在庫品目があり、経理と共有されることになる。

##モジュール・サービス
+ 「境界付けられたコンテキスト」を整理したら、「**共有モデル**」（他のコンテキストと共有するもの）と「**隠れモデル**」（内部だけで完結するもの）を備えた**モジュール**としてモデル化する。
+ この**モジュール境界がマイクロサービスの候補**になる。
+ **サービス化**（マイクロサービスとして分割）において、**サービス境界を間違えると改修が高コストになる**ため、新規システムではよりモノリシックな状態にしておく方が賢明である。あとで分割を進めればよい。（ThoughtWorksの例では境界を誤り、一度モノリスにしてから再度分割を行った。）
+ **サービス境界（マイクロサービス）がコンテキスト境界と一致**していれば、高い凝集性を持った状態になる。


##ビジネス機能
+ 組織のコンテキスト境界の観点は、そのコンテキストが他のドメインに提供する機能を考えるべきである。（データではない）
+ 機能には情報交換（共有モデル）が必要になることもあるが、そこに注目してしまうとCRUDになる。それはよくない。
+ 「このコンテキストは何を行うか」「それを行うためにはどんなデータが必要解」を考える。
+ サービスの機能は操作を通してモデル（データ）が共有される、ということ。

##トップレベル
+ コンテキスト境界で共有されるモデルはトップレベルコンテキスト（トップレベルマイクロサービス）となる。
+ その他のモデルは隠れモデルのまま（入れ子構造）とするか、共有モデル（トップレベルモデル）とするかという選択肢がある。
+ そのように選択するかは、組織構造に基づくべきである。（ex.組織が同一なら隠れモデルとする。）

##ビジネス観点での通信
+ システムの変更は、ビジネス観点での振る舞いを変更することである。
+ サービス間の通信もビジネス観点で考えるべきである。
+ サービス間の通信形式を考えることは、組織内（組織間？）の書類形式を考えることと同様の価値がある。

##技術的境界
+ 技術観点で境界を設ける方法もあるが、これが第一条件であってはならない。
+ 例えば、通信形式を変更したい場合、垂直方向の分割がされていると変更箇所が多岐に渡るためコストがかかる。技術的観点が必ずしも悪いわけではないが、あくまでも第二条件であるべき。

つづきは[こちら](https://sik-bug.hatenablog.com/entry/2020/08/16/115545)