マイクロサービス(英語:microservices)とは、ソフトウェア開発の技法の1つであり、1つのアプリケーションを、ビジネス機能に沿った複数の小さいサービスの疎に結合された集合体として構成するサービス指向アーキテクチャ(service-oriented architecture; SOA)の1種である。マイクロサービスアーキテクチャでは、各サービスはきめ細かい粒度を持ち、軽量なプロトコルを用いて通信を行う。

アプリケーションを異なる小さなサービスに分割することの利点は、モジュラリティが高くなることである。これによって、アプリケーションの理解、開発、テストがより簡単に行えるようになり、アーキテクチャの腐敗に対する弾力性が向上する。マイクロサービスによる開発を行うことで、開発が並列化され、少人数の自律的なチームにより、各チームが所有するサービスを独立に、開発、デプロイ、スケールさせることが可能になる。また、継続的リファクタリングを通して、個々のサービスのアーキテクチャ全体を置き換えることも可能になる。マイクロサービスベースのアーキテクチャでは、継続的デリバリーと継続的デプロイが可能になる。

## 概要

2014年、ThoughtWorks社のマーチン・ファウラーとジェームス・ルイスが提唱したソフトウェアアーキテクチャである。

何がマイクロサービスであるか、という公式な定義は存在しないが、業界では徐々にコンセンサスが形成されつつある。マイクロサービスを特徴づける定義としてよく引き合いに出されるものとしては、以下のような点が挙げられる。

- マーティン・ファウラーや他の専門家たちによれば、マイクロサービス・アーキテクチャ(microservice architecture; MSA)は、特定の技術にとらわれないHTTPなどのプロトコルを使用して、目的を達成するためにネットワーク越しのコミュニケーションのプロセスを実行する。ただし、サービスは共有メモリなどの他の種類のプロセス間通信のメカニズムを使用することもある。また、たとえばOSGIバンドルなどのように、同一のプロセス内で実行される場合もある。
- マイクロサービス・アーキテクチャにおけるサービスは、独立にデプロイが可能である。
- サービスは、きめ細かい粒度のビジネス機能を中心に組織される。マイクロサービスにおいて粒度は重要である。なぜなら、粒度こそ、このアプローチをSOAと異なるものにしているからである。
- 各サービスに最も適した異なるプログラミング言語、データベース、ハードウェアおよびソフトウェア環境で開発することができる。これは、1つのマイクロサービスがさまざまなプログラミング言語のパッチワークのように書かれるという意味ではない。
- サービスはサイズが小さく、メッセージングを行い、コンテキストによって境界づけられ、自律的に開発される。また、中央集権的ではなく、独立してデプロイが可能である。そして、自動化されたプロセスにより、自動ビルドと自動リリースが実行される。

マイクロサービスは、モノリシックなアプリケーション内にある1つのレイヤー(たとえば、ウェブコントローラや、フロントエンド向けバックエンド(backend-for-frontend))ではない。むしろ、自身のみでビジネス機能を提供する、明確なインターフェイスを持った小さなピースである(サービス内部のコンポーネントとしてレイヤーアーキテクチャを実装することさえある)。戦略的な観点からは、マイクロサービスは 「ただ1つのことをして、それをうまくやる」というUnix哲学に本質的には従っているものとして考えられる。マーティン・ファウラーは、マイクロサービス・アーキテクチャには次のような性質があると述べている。

- 当然のものとしてモジュラー構造を強制する。
- 継続的デリバリーのソフトウェア開発プロセスに向いている。アプリケーションの小さなパーツを変更しても、1つか少数のサービスのみをリビルドして再デプロイすればよい。
- きめ細かい粒度のインターフェイス(デプロイ可能なサービスからは独立したもの)、ビジネス駆動開発(たとえば、ドメイン駆動設計など)などの、いくつかの定義された原則(principles)に従う。

なお、「マイクロサービス」という用語は、2011年5月にヴェネツィア近郊のソフトウェアアーキテクトのワークショップで議論され、参加者が最近調査した共通のアーキテクチャースタイルと見なした内容を提唱者らが説明している。2012年5月、同グループが最も適切な名前として「マイクロサービス」を決定した。

## 特徴

提唱者らは下記に述べる特性を挙げているがこれらは定義ではなく、すべての特性をもつ必要はないとしている。

- サービスのコンポーネント化 - コンポーネントは独立して交換・更新可能なソフトウェアの単位である。

- ビジネス中心組織 -開発運用チームは技術や開発工程によるチームではなく、ビジネスを中心に機能横断型のチームが編成されている。

- プロジェクトではなくプロダクト - チームは開発完了とともに解散するプロジェクトモデルではなく、製品のライフサイクル全体に責任を持つ。

- スマートエンドポイントとダムパイプ - メッセージ通信は軽量かつシンプルであること。エンドポイントに高い機能を持たせ、通信はダムパイプ(メッセージのルータとしてのみ動作する単純な機構)であること。

- 分散統治 - 各サービスは独立したチーム、開発言語、ツールでアプローチする。

- 分散データ管理 - 概念モデルに関する分散だけでなく、データストレージも分散(サービス間で独立)する。

- インフラストラクチャの自動化 - テスト自動化/継続的デリバリー/継続的インテグレーションの導入

- 障害の設計 - 個々のサービスはいつでも失敗する可能性があるため、互いに障害を迅速に検出し、可能であれば自動的にサービスを復元できることが重要。

- 進化的な設計 - 頻繁に、迅速に、適切に制御されたソフトウェアの変更・廃止・構築を行うことができること。

## 背景

従来のソフトウェアアーキテクチャは単一のアプリケーションとして構築されたモノリシックアーキテクチャが主流であった。しかし、ビジネスや環境の変化とともにアプリケーションへの変更サイクルが短くなり、特にモノリシックアーキテクチャの場合はアプリケーション全体を再構築して展開する必要がある。時間の経過とともに、適切なモジュール構造を維持することは難しいため、そのモジュール内の1つのモジュールにしか影響を与えない変更を維持するのが難しくなってしまう。

技術の発展とサービスの多様化に伴い、モジュールが独立して展開可能でなおかつスケーラブルであるようになる。
また、堅固なモジュール境界を提供し、それぞれの機能が異なるプログラミング言語で書かれることを可能にした。さらに、異なるチームによって開発・運用管理することもできるようになることで、一部の変更が全体へ影響を及ぼすことへのリスクがサービスの独立によって解消できるアプローチスタイルが出来上がった。

## 課題

モノリシックアーキテクチャと比較し、下記の欠点を上げている。

- 共通化基盤とコンポーネント境界をどこに定めるべきかが困難 - リリースや変更するサービス単位が境界になるがビジネスやマーケットに左右される。

- インターフェース変更に伴うリファクタリング - サービス境界全体では変更が難しく、参加者間でインターフェイスの変更を調整する必要があり、かつ後方互換性のレイヤーを追加する必要があり、テストがより複雑になる。

- 複雑化されたコンポーネント - コンポーネントがきれいに構成されていない場合、コンポーネント内からコンポーネント間の接続へ複雑さがシフトしてしまいそれがさらに波及するリスクがある。

- チームスキル - スキルが高いチームに効果的な技術は、スキルの低いチームでは必ずしも機能しない。この問題が一部のマイクロサービスに混入した場合、システム全体に影響する可能性がある。

## 方法論

### 提唱当初のプラクティス

2014年当初の提唱者らは「マイクロサービスがソフトウェアアーキテクチャの将来の方向性であると確信していると主張しているわけではない」と語る。

アプローチのひとつとしては、マイクロサービスアーキテクチャから始めるべきではないということ。代わりにモノリスで始め、モジュール化したままにし、モノリスが問題になったらマイクロサービスに移行・分割していく。

### サービスメッシュ

マイクロサービスを構成するネットワーク基盤をサービスメッシュと呼び、ネットワーク基盤をアプリケーションから隠蔽することでマイクロサービスをより容易に実現しようと試みられている。

サービスメッシュ(Service Mesh)は、アプリケーションを構成するマイクロサービス群からなるネットワークである。マイクロサービス間通信を用いてアプリケーションを構成するには、データ転送の制御と監視が必須である。要件の例としては以下が挙げられる。

- サービスディスカバリ
- 負荷分散
- 障害復帰
- メトリクス
- 監視

さらにA/Bテストやカナリアデプロイ、レート制限、アクセス制御、認証、カオスエンジニアリングなど様々なネットワーク関連の要件が発生しうる。サービスメッシュに着目した場合、ネットワークに由来するこれらの困難さをアプリケーションから隠蔽するためにプロキシなどの様々な手法が用いられる。

ネットワークの転送部は転送を担うデータプレーン(data plane)と転送制御を決定するコントロールプレーン(control plane)に分離できる(c.f. Software Defined Networking)。アプリケーションからデータプレーンおよびコントロールプレーンを分離することでアプリケーションからサービスメッシュを隠蔽する手法が主流である。

例えばEnvoyはService Meshにおけるデータプレーンプロキシである。Envoyプロキシは各マイクロサービスに同梱され、Envoy間で通信を行うことでサービスメッシュを構成する。マイクロサービスは同梱されるEnvoyプロキシのみを見ているため、サービスAppにとってサービスメッシュは透過的に扱われる(隠蔽されている)。Eovoyデータプレーンが利用する制御情報は別に用意されたコントロールプレーンから提供される(例: humanコントロールプレーンによる静的設定ファイル、Istioによるコントロールプレーンサービス)。

クラウドコンピューティングによるマネージドコントロールプレーンも提供されている。例えばAmazon Web ServicesはAWS App MeshによりEnvoyをデータプレーンとしたマネージドコントロールプレーンを提供している。