マイクロサービスアーキテクチャの特徴を学ぼう! メリット・デメリットや設計の指針とは

近年、マイクロサービスアーキテクチャが流行しています。さまざまな利点を持つマイクロサービスアーキテクチャですが、けして万能ではありません。特徴を理解して適切に活用しなければ、その利点を最大限に発揮できなくなってしまいます。今回はマイクロサービスアーキテクチャの概要やメリット・デメリット、アーキテクチャ設計における考え方について解説します。

マイクロサービスアーキテクチャとは

マイクロサービスアーキテクチャとは、モノリシック(一枚岩)なサービスを、ビジネス機能に沿って複数の小さなサービスに分割するアーキテクチャのことを指します。各システムをさまざまな手法で分散・協調させて、あたかも大きなひとつのシステムの集合体であるかのように見せることが特徴です。

例えば、読者のみなさんのなかには、ECサイトのAmazonをご利用された経験のある方もいるでしょう。Amazonはマイクロサービスアーキテクチャを導入しているシステムの代表例です。「商品情報を扱うシステム」「(商品を入れるための)カートを管理するシステム」「メール配信システム」など複数のシステムが連動しあって、Amazonというひとつのサービスが提供されています。他にもNetflixやLINEなど、私たちにとって身近なサービスにもマイクロサービスアーキテクチャは導入されています。

なぜ、マイクロサービスアーキテクチャが採用されるのでしょうか。その理由のひとつは、「サービスを細かい単位に分割することで、変更要求への対応スピードを向上させることができ、かつ変更のコストを下げられるため」です。では、モノリシックなサービスとマイクロサービスとでは、システム変更の流れがどのように異なるのかを比較してみましょう。

モノリシックなサービスの場合、システムが単一のリポジトリ(もしくは粒度の大きい複数のリポジトリ)として管理されているため、ある機能のリリースが他の機能にも影響してしまう可能性があります。

例えば、社員情報を管理するシステムにおいて、機能A・B・Cという3種類の機能が存在しているとしましょう。このうち、機能Aを修正したことによりバグを埋め込んでしまい、その影響でシステムがダウンした場合、機能B・Cも使えなくなってしまうケースが多いです。なぜなら、システムそのものが単一であるため、ある機能の障害が他機能にも波及してしまうからです。

こうした事態を避けるために、モノリシックなサービスにおいては「機能の修正・リリースを行う際には、関係するすべての部署やチームとの調整作業を行う」「ある機能の修正が他の機能に悪影響を及ぼさないよう、入念にテストをする」などの必要性が生じます。つまり組織やサービスの規模に比例して、機能変更に必要な時間的・人的コストも大きくなってしまうのです。

マイクロサービスを導入することで、こうした事態を防ぐことができます。例えば、先ほどのサービスをマイクロサービス化する場合には、機能A・B・Cをそれぞれ独立したサービスとして分割します(もちろん、異なる単位で分割するケースもあります)。それにより、機能Aの修正・リリースが他の機能に及ぼす影響を最小限に抑えられるというわけです。

この説明だけを聞くと「マイクロサービスとはシステム分割のことなのだろうか」と思う方もいらっしゃるかもしれませんが、両者は異なります。マイクロサービスはシステムの変化だけではなく、組織構造の変化が伴うことが大きな特徴です。

マイクロサービスの場合、組織構造そのものも機能ごとに明確に分割し、各チームに独立した意思決定を許容します。つまり、「○○の機能を追加しよう」「○○のタイミングでリリースする」という判断を、各サービスの担当チームが個別で行うのです。これにより、各部署や各チームとの調整・承認にかかるコミュニケーションコストが大きく削減されます。

マイクロサービスアーキテクチャのメリット・デメリット

ここからは、マイクロサービスアーキテクチャにはどのようなメリット・デメリットがあるのかを順に解説していきます。

メリット

1. サービスの機能に合わせて最適な技術を採用できる

マイクロサービスアーキテクチャでは、各サービスで使用する技術に制約がありません。例えば「サービスAでは並列処理を行いたいのでGo言語を採用するが、サービスBでは開発効率を重視するためにRubyを採用する」などの柔軟な技術選定が可能になります。すべての機能が単一のシステムとして動くモノリシックなアーキテクチャでは、こうした技術選定は困難でした。

2. 障害の影響を局所化できる

もしも特定のサービスで障害が発生したとしても、システムがマイクロサービス化されていれば、その影響を他サービスに波及させることなく局所化できます。

3. システムリソースを効率よく利用できる

システムを運用していると「複数の機能のうち、ユーザーは特定の機能のみを頻繁に使うが、他の機能をあまり使わない」といったケースはよく発生します。こうしたケースにおいて問題になるのが、特定機能に対するトラフィックが増えてサーバへの負荷が高くなったときです。

モノリシックなアーキテクチャの場合には、よく使われる機能はごく一部であるにもかかわらず、システム全体のスケーリングを行わなければいけません。一方、マイクロサービスアーキテクチャの場合はよく使われる機能(サービス)のみをスケーリングさせればいいため、システムリソースの利用効率がよくなります。

4. 新規機能やバグ修正を迅速にシステムに反映できる

こちらは、先ほどの章でも解説した内容です。マイクロサービスアーキテクチャでは特定機能の修正・リリースが他機能におよぼす影響を低減でき、かつ各サービスチームが独立した意思決定を行います。機能改修の効率が向上し、新規機能やバグ修正をスピーディーにシステムへと反映できるようになるのです。

デメリット

1. サービス間の通信頻度が増えることに起因したトラブルが発生しやすい

マイクロサービスアーキテクチャでは、複数のサービスがAPIを用いて相互に連携します。そのため、複数回のネットワーク通信が発生することでシステムのパフォーマンスが劣化する可能性がありますし、通信エラーに起因した障害が発生することもあります。

2. データの一貫性を保証することが難しい

マイクロサービスアーキテクチャでは、サービスごとにデータストアを分割します。また、複数のサービス同士が非同期にデータを分散処理するケースもよくあります。そのためサービスをまたぐような処理をする場合に、データの一貫性を保証することが難しくなってしまうのです。

3. サービス分割の仕方を、あとで変更することが難しい

ひとたびサービスを分割してしまえば、分割の仕方をあとで変更することは困難になります。そのため、マイクロサービス化を推進する前の段階で、どのような境界でサービスを分けるべきなのかを慎重に考える必要があります。

4. アーキテクチャ設計の難易度が上がる

「サービス同士をどのように連携させるべきか」「API呼び出しが失敗した場合、リトライやサーキットブレーカーなどの処理をどのように実施するか」など、マイクロサービスアーキテクチャには設計における特有の課題が発生します。そのため、モノリシックなアーキテクチャと比較するとアーキテクチャ設計の難易度は高いと言われています。

マイクロサービスアーキテクチャにおける分割単位

ここからはマイクロサービスアーキテクチャにおいて、サービスやデータベースを分割する際の指針を解説していきます。

サービスの分割単位

マイクロサービスアーキテクチャにおいて「どのような単位でサービスを分割するか」はとても重要な観点です。分割する単位が大きすぎると、単なる「いくつかの塊に分けただけのモノリシックなサービス」のような状態になり、マイクロサービスアーキテクチャの利点を享受できなくなってしまいます。

一方、分割する単位が小さすぎる場合にも別の問題が生じます。例えば、企業情報を管理するシステムにおいて「部署の情報」と「社員の情報」を扱うための機能を、別々のサービスに分割してしまった場合を考えてみましょう。

両者の情報はとても関連性が高いですから、どちらか一方の機能変更は確実にもう一方のサービスに影響してしまうはずです。つまり、依存度の高い連携がサービス間で発生してしまい、密結合になってしまいます。これでは、マイクロサービスの利点を発揮できません。

サービスを分割する際には「分割することで開発効率は向上するか」「各サービスの独立性は高いか(あるサービスの変更影響が他のサービスに波及しないか)」「サービス分割により技術的な選択肢が広がるか」などの点を心がけるようにしましょう。

データベースの分割単位

モノリシックなアーキテクチャにおけるデータ管理の基本は、特定のデータベースを複数の機能(サービス)で共有する一元管理方式です。しかし、マイクロサービスでは多くの場合、各サービスが必要とするデータを分散して管理します。

なぜなら、マイクロサービスアーキテクチャにおいて複数のサービスで共通のデータベースを共有すると、データベースを起点として各サービスが密結合になってしまうためです。要するに、あるサービスが実施したデータベース変更により、他のサービスに悪影響が出てしまう可能性が生じます。

この問題を避けるため、マイクロサービスアーキテクチャにおいては各サービスで扱うデータを個別で保管・管理し、他のサービスからは直接的にアクセスできないようにしておくべきなのです。

マイクロサービスアーキテクチャとコンテナとの関係性

よく「マイクロサービスアーキテクチャを採用する際には、一緒にコンテナも導入した方がいいのだろうか」という疑問を持たれる方がいらっしゃいます。もちろん、コンテナを運用するための各種ツールやプラットフォームがマイクロサービスのアプリケーションを管理する手段として優れているのは確かですが、両者はセットではありません。

例えば、前半パートでご解説したAmazonの開発チームのなかにも、コンテナではなく仮想マシンやサーバーレス技術などを用いてサービスを開発・運用するチームもいます。彼ら・彼女らはサービスに求められる要件や特性に応じて、適切なコンポーネントを選定しているのです。「マイクロサービスアーキテクチャだから、○○の技術を用いなければ」という考え方で技術選定を行うことはありません。ではなぜ、「マイクロサービス=コンテナ」というイメージを持たれるようになったのでしょうか。

近年、さまざまな技術が進歩したことによって、システムを分散・協調させる環境が整ってきました。例としては、以下のような要素が挙げられます。

・各種クラウドベンダーが提供するさまざまな実行環境サービスの充実化
・システム間の通信プロトコルの整備
・サービスメッシュの普及による、ネットワーク起因トラブルの低減や通信の可観測性向上
・マイクロサービスに向いたフレームワークやライブラリの登場
・DockerやKubernetesの登場によるコンテナ仮想化技術の一般化

これらの技術の普及とマイクロサービスアーキテクチャの流行が同時期に起きたことにより、あたかもこれらの新技術がすべてマイクロサービスに必須であるかのようなミスリードが起きてしまったのです。しかし、けしてそんなことはありません。

上記のような要素技術が自分たちに必要なのかを考えたうえで、適切に取捨選択していく姿勢がエンジニアには求められます。ときには、これらの技術をあえて採用しないという選択が最善のケースもあるはずです。むしろ、マイクロサービスと特定の技術がセットであるかのように捉えてしまうと「各サービスが自由度の高い技術選定を行える」という、マイクロサービスの重要なメリットのひとつが失われてしまいます。

おわりに

マイクロサービスアーキテクチャは非常に流行している技術ではあるものの、他のアーキテクチャと同じように利点・欠点のどちらもあります。自分たちの開発組織や担当サービスにマイクロサービスが適しているかを冷静に考えて、適切な意思決定を行っていきましょう。

FLEXYとはABOUT FLEXY

いい才能が、集まっている。いい仕事も、集まっている。

『FLEXY』はエンジニア・デザイナー・CTO・技術顧問を中心に
週2-3日 x 自社プロダクト案件を紹介するサービスです