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

## はじめに
[**Azureクラウドアプリケーションアーキテクチャガイド**](https://azure.microsoft.com/ja-jp/campaigns/cloud-application-architecture-guide/)より、7つあるアーキテクチャスタイルの一つ、**マイクロサービス**に関してまとめます。

#### 連載目次
[Azureアーキテクチャガイドまとめ 1 【はじめに】](https://qiita.com/Catetin0310/items/74249f333d9fbfccd543)
[Azureアーキテクチャガイドまとめ 2【N層】](https://qiita.com/Catetin0310/items/1ab0ae1130f767d770d3)
[Azureアーキテクチャガイドまとめ 3 【Webキューワーカー】](https://qiita.com/Catetin0310/items/fe0729549faeee843e8a)
Azureアーキテクチャガイドまとめ 4 【マイクロサービス】 → 本記事
[Azureアーキテクチャガイドまとめ 5 【CQRS】](https://qiita.com/Catetin0310/items/d0e8b489f6501e4da90b)
[Azureアーキテクチャガイドまとめ 6 【イベントドリブンアーキテクチャ】](https://qiita.com/Catetin0310/items/58f65242a7b71620825b)
[Azureアーキテクチャガイドまとめ 7 【ビッグデータアーキテクチャ】](https://qiita.com/Catetin0310/items/d515fc3fdff68b54f408)
[Azureアーキテクチャガイドまとめ 8 【ビッグコンピューティングアーキテクチャ】](https://qiita.com/Catetin0310/items/eebd754637dcda8ad14d)


## 対応するAzureサービス
今回はやや長くなるので、最初にマイクロサービスアーキテクチャで活用されるAzureサービスをまとめます。

**サーバレス**であれば**Azure Functions**、**コンテナ**であれば**Azure AKS**がコアサービスになります。


![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/3949db84-c588-f530-7cc2-63bbf7859c89.jpeg)
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/7bbca1b2-3064-30ad-7f7a-7bccecb5cd6e.jpeg)



どちらの場合も、以下のコンポーネントで構成されます。

- **サービスを体現するコンポーネント**
    - ドメイン駆動設計でいうモデルを実装しているアプリケーションが動作するコンポーネント

- **管理**
    - サービスのノードへの配置
    - 障害の発見
    - ノード間でのサービスの再調整
- **サービス検出**
    - サービスとそれが配置されているノードのリスト保持
    - サービスのエンドポイントを知るためのサービス検索機能
- **APIゲートウェイ**
    - クライアントのためのエントリポイント
    - クライアントをサービスから分離
    - Webと親和的ではないメッセージングプロトコルでも対応
    - 横断的機能の実行
        - 認証
        - ログ記録
        - SSLターミネーション
        - 負荷分散

コアサービスとともに併用されるサービスも一覧にしておきます。
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/abab7032-92c1-6535-404c-45bdf7dc0448.jpeg)

構成図にするとこのような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/eea68d3e-221b-ba84-d502-9ac80341d2e0.png)


## ちょっと寄り道
どんなサービスがあって、どのように組み合わせるのか、おぼろげながらイメージできました。

数あるサービスの中でも専門性が高く、しかも進化が続いているアーキテクチャだけに、ガイドだけだとなかなか理解が進まなさそう、というのが正直なところ。

そこで、いったんガイドを離れ、理解が進みやすいような情報をつまみ食いしようと思います。


### ドメイン駆動設計って何ぞ？
マイクロサービスアーキテクチャの設計で避けて通れないのが、**ドメイン駆動設計** (Domain-Driven Design, DDD)。

設計の勘所はAzure公式ドキュメントに網羅されているのですが、専門用語が多く、頭になかなか入りません。

そこで、[**こちら**](https://qiita.com/little_hand_s/items/721afcbc555444663247)の記事を参考にさせていただき、概要を図示しました。

![DDD (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/5225a0db-f28f-1a05-2060-52f5eee91e0d.jpeg)

先の表や後述する内容と重複しますが、マイクロサービスアーキテクチャには多くの利点がある反面、**仕組みも管理も複雑**になりやすいという傾向があります。

しかも、ドメインにフォーカスし続けて開発するためには、ステークホルダー間の**認識の祖語を最小限**にするメソッドを明示しておく必要があります。

この開発手法を体系化したものが**ドメイン駆動設計**、と理解しました。大枠はこれで大丈夫(のはず)。

### サーバレスとコンテナの比較
[**Azureアーキテクチャセンター**](https://docs.microsoft.com/ja-jp/azure/architecture/)にサーバレスとコンテナの比較がありました。革新が早い技術ですので、とりあえずベースラインの知識として頭に入れておきたいところです。

![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/2f969573-bc5d-7bb5-7f96-804ea7532d3c.jpeg)



## 概要
さて、ここでガイドに戻ります。アーキテクチャスタイルの特徴を挙げてみましょう。

- 小規模な**自律的サービスの集合**
- 各サービスは**自己完結型**で、**疎結合**
- 各サービスは**別個のコードベース**
- 各サービスは明確に定義された**API**を使用して互いに通信


具体的には、以下のような特徴を持つアプリケーションに適しています。

- **高速なリリース**が必要
- **大規模**
- **高い拡張性**が必要で**複雑**
- **多様なドメイン**や**多数のサブドメイン**を持つ
- **複数の小規模な開発チーム**から構成される組織によって作られる






## 利点
- 独立した展開
    - アプリ全体を**再展開せずにサービスを更新**
    - バグ修正と機能リリースの**管理の容易さ**

- 独立した開発
    - **継続的なイノベーション**の実現
    - **リリースのペース**を速める
    - 一つの開発チームが、サービスの構築、テスト、展開を行える
- 小規模な専任チーム
    - チームは**一つのサービスに専念**
    - コードベースが分かりやすくなり、新しいチームメンバーでも理解しやすい
- 障害の分離
    - サービスがダウンした場合でも、その部分以外はサービス継続できる。
    - とはいえ、回復性が自動的に得られるわけではない点に留意。
- テクノロジスタックの混在
    - 各サービスが**違ったテクノロジスタッフ、フレームワーク**を持つことを許容する
    - つまり、特定のサービスに**最適な技術を選定**できる 
- きめ細やかな規模拡張
    - 各サービスは**独立に拡張可**
    - マシンリソースの効率的活用


## 課題
- 複雑性
    - 相当する、複数の機能を持った単一のアプリ(モノリシックアプリケーション)に比べ、**多くの可動部分**があり**管理が複雑**

- 開発とテスト
    - 既存のツールは、サービスの依存関係を考慮するように設計されていない場合あり
    - サービスの境界を超える**リファクタリング**が困難な場合も
    - 特にアプリケーションが急速に進化している場合には、**サービスの依存関係テスト**は困難に
- ガバナンスの欠如
    - 使用される言語やフレームワークが多くなりすぎると**アプリの保守**が困難に
    - 特にログ規則などの横断的機能に対して、何らかの**基準**を設けたほうが良い
- ネットワークの輻輳と待ち時間
    - サービス間通信の増加で**待ち時間が増える可能性**
    - 適切な場合には、非同期通信パターンを使用すること。
- データ整合性
    - 各サービスが自身のデータ永続性に責任を負う必要がある
    - 可能な場合は、結果整合性を採用する
- 管理
    - **成熟したDevOpsカルチャー**が不可欠
    - **サービス間でのログの相関**が課題になることも
- バージョン管理
    - **慎重に設計**しないと、過去または将来との互換性に問題が生じることも
- スキルセット
    - チームに成功のためには**スキルと経験**が求められる

## ベストプラクティス
- **ビジネスドメイン**を中心にモデル化する

- すべてを**分散**する。
- 設計と構築には、**個々のチームが責任**を負う
- コードやデータスキーマの共有は避ける
- サービスは**疎結合**にし、機能の**凝集度を高く**する。
- 二つのサービス間の通信量が多すぎる場合は、結合が密で、凝集度が低い可能性あり
- **障害を分離**する
- データストレージ
    - データを所有するサービス専用にする
    - データの種類に応じてストレージを選択
- API
    - サービスの内部実装ではなく、ドメインをモデル化する
- ゲートウェイ
    - 認証やSSLターミネーションなどの**横断的な作業**を行う
    - ドメインの知識を持ち込まない


## まとめ
マイクロサービスの特徴と使用されるサービスについて見ていきました。いやー難しい。次回はCQRSアーキテクチャスタイルについてまとめます。お楽しみに！

## 参考リンク
[**Azureアーキテクチャセンター**](https://docs.microsoft.com/ja-jp/azure/architecture/)
[**Azureでのマイクロサービスの実装**](https://docs.microsoft.com/ja-jp/azure/architecture/microservices/)
[**ドメイン駆動設計は何を解決しようとしているのか[DDD]**](https://qiita.com/little_hand_s/items/721afcbc555444663247)