アプリケーション・モダナイゼーション: マイクロサービスのメリットって?

レッドハットのソリューションアーキテクトの森です。

今回は、アプリケーション・モダナイゼーションの話についてです。

企業のDXを実現するために、レガシーなシステムをマイクロサービス化する、という話は、皆さん一度は耳にしたことがあるのではないでしょうか。

しかし一方で、全てのシステムに対して、マイクロサービス化をすることが最適解というわけではありません。そこで、マイクロサービスの特徴や、開発・運用するにあたって必要な要素、実際に移行する際の方法論などを数回に分けてご紹介していきたいと思います。

そもそもマイクロサービスって何?

マイクロサービスとは、サービスと呼ばれる、独立して開発されて稼働するコンポーネントを、複数組み合わせて1つのアプリケーションとして構成するものです。各コンポーネントは別々のマシン(あるいはサーバー、またはコンテナ)に分かれており、1つのリクエストに対して、RESTやメッセージングによる通信でデータを送り合うことで処理を行います。この小さな単位に分割された構造と分散コンピューティングが、マイクロサービスの大きな特徴です。

サービスの分割の粒度ついては、こちらの記事も参照して頂ければと思います。

rheb.hatenablog.com

マイクロサービスについての理解を深めるために、従来型のアーキテクチャとの比較をしてみましょう。

よく、マイクロサービスとの対比で引き合いに出される従来型のアーキテクチャに、モノリス(またはモノリシック)と呼ばれるものがあります。モノリスは、英語で「一枚岩」という意味ですが、よくある形としては、3層構造(ユーザーインターフェイス、ビジネスロジック、データ)で構成されているものが多いかと思います。また実際には、ビジネスロジックも内部的にはいくつかの機能ごとに分かれていると思います。ここでは、複数の機能が単一のアプリケーションで構成されるもの、として考えてみます。


図1:モノリスとマイクロサービスの違い

モノリスとマイクロサービスの違い

上記で見た構造の違いにおいて、モノリスとマイクロサービスにはそれぞれメリット・デメリットがあります。 その内容を、以下の表のように整理をしてみました。


図2:モノリスとマイクロサービスのメリット・デメリット

敏捷性

従来のモノリスにおいても、アプリケーションの中は複数の機能から構成をされています。開発もその単位では行われるものの、アプリケーションとしては単一のモジュールとなっており、各機能は独立しておらず依存関係があります。そのため、ある機能が先行して開発を完了したとしても、他の機能との整合性が取れていないと稼働することができず、全ての機能の開発の完了を待ってリリースをする必要があります。

しかし、マイクロサービスを適用してアプリケーションを小さい単位に分割をしていれば、サービスごとに独立した開発やデプロイが可能となります。結果として開発・リリース速度の向上が期待でき、ユーザーも速やかに新しい機能を使うことができるようになります。


図3:敏捷性

独立性

モノリスでは、開発に使うプログラミング言語や製品などもアプリケーションで共通のものを使用する必要があるため、個々のアプリケーションやチーム特性に対して最適化することはできません。

対してマイクロサービスでは、サービスごとに異なるプログラミング言語や開発手法を採用することが可能になります。プログラミング言語には、用途によって向き不向きがあるため、サービスごとに適した言語を選択できることは、開発効率の最適化に繋がります。


図4:独立性

保守性

モノリスでは、アプリケーションの改修を繰り返す度に、プログラムは大きく、複雑化していき、機能間の結合度も密になって行きます。そして複雑化したアプリケーションでは、「プログラムが複雑なため機能追加がしにくく、バグも発生しやすい」「機能が多く巨大なためテストに時間がかかる」「システム全体に影響する可能性があるため、気軽にデプロイできない」といった問題が発生しやすく、高速な開発の足枷となってしまいます。

その点、マイクロサービスにおいては、サービスの境界を明確することで、機能追加における影響範囲を限定し、分かりやすくなります。そのため改修の難易度は低くなり、テストも変更箇所のみとすることができます。


図5:保守性

拡張性

アプリケーションの性能に問題がある場合は、サーバのCPUやメモリ等のハードウェアの増強をするか、アプリケーションを並列稼働して分散処理を行うことで、全体の処理能力を向上させる必要があります。モノリスの場合には、一部の機能の性能に問題があったとしても、アプリケーション全体を、よりスペックの高いハードウェアに載せ替えたり、並列稼働させる必要がありました。ここには性能対策が不要な機能も含まれるため、リソースの使用効率は低くなります。

マイクロサービスでは、サービスごとに負荷分散やスケールが可能です。アプリケーション全体ではなく、負荷の大きいサービスのみをスケールさせられるという柔軟性と、負荷の低いサービスはスケールしなくてよいため、リソース最適化の容易さを兼ね備えています。


図6:拡張性

可用性

一部の機能で障害が発生した場合、モノリスではアプリケーション全体が落ちてしまい、障害の復旧まで全ての機能停止してしまいます。

マイクロサービスを適用していた場合は、特定の機能に障害が発生しても、他の機能は稼働を継続することが可能で、障害の影響を局所的に抑えることができます。そのため、アプリケーション全体の耐障害性を向上させることができます。


図7:可用性

再利用性

新しい業務システムを作る際に、既存のアプリケーションの中の一部機能と同じものが必要になることがあります。既存のアプリケーションの機能を流用し、足りない機能を追加してリリース・・・としたいところですが、新しい業務システムには不要な機能も、既存のアプリケーションには含まれていることがあります。そのまま既存のアプリケーションに機能追加を行っていくと、アプリケーションが複雑化していくことになるため、効率化のために既存のソースコードを流用し、新規のアプリケーションとして開発を始めるケースもあります。その場合は、既存の不要な機能も含めてコピーしてしまう点と、同じ機能が複数のアプリケーションに存在し、二重管理をとなる点が課題になってきます。

マイクロサービスであれば機能を分割しているため、新しいアプリケーションを作る際にも、既存の機能をそのまま流用して開発をすることが容易です。これにより、開発のボリュームが減り、ビジネスのニーズに合わせた迅速なシステム変更にも対応ができるようになります。


図8:再利用性

パフォーマンス

ここまでは、従来のモノリスと比較して、マイクロサービスが優れている点を紹介してきました。しかし、もちろん良いことばかりではありません。その構造によるデメリットも存在します。

マイクロサービスでは、アプリケーションの1リクエストを完結するために、複数のサービスがAPIを用いて相互に連携します。そのため、複数回のネットワーク通信が発生することでシステムのパフォーマンスが劣化する可能性があります。また例えば、RESTなどの同期通信のみで構成した場合には、仮にどこかのサービスで何か障害が発生したとすると、そのサービスを起点に下流側の機能が全て止まってしまうことになります。そのため、処理の途中でエラーとなった際の対応などを考慮する必要があります。これに対しては、非同期通信にてサービス間の連携を行うやり方もあり、詳細については次回のブログでお話しします。


図9:パフォーマンス

データ管理

マイクロサービスの設計の方針の1つに、疎結合があります。各サービス間の依存関係を疎にすることで、素早く柔軟に変更を行うことができるようになります。これは、アプリケーションだけでなくデータベースも含まれます。ビジネス側の要望により、データベースのスキーマ変更が必要になるケースもあるでしょう。その際の設計変更要求に対して柔軟な対応ができるように、サービスとデータベースの関係を1:1とするモデルが推奨されます。しかしその一方で、サービスをまたぐような処理をする場合に、データの一貫性を保証することが難しくなってしまうという課題があります。


図10:サービスとデータベースは1:1

マイクロサービスにおいて、複数のデータベース間の同期については、「結果整合性」が許容できないか、ということも考慮に入れて検討していくことが重要です。IT側の人間だけでは判断が難しいので、ビジネス側のエキスパートとよく業務要件を確認し、データベース間の同期/整合性の設計を進めると良いでしょう。

運用・監視

マイクロサービス化が進むにつれて、アプリケーションは小さな単位に分割をされていきます。大規模なシステムの場合には、その数が数百〜数千に及ぶこともあり、手動によるサービスの管理は現実的に不可能でしょう。またマイクロサービスの各サービスは、コンテナを利用してデプロイするのが一般的となっていますが、コンテナの管理もサービス同様に煩雑となりがちです。そのため、コンテナのオーケストレーションシステムとして、デファクトスタンダードとなっている Kubernetes や、サービスメッシュの導入を併せて検討するのがお勧めです。

マイクロサービスはどのようなシステムに適用すべきか?

ここまで見てきたように、マイクロサービスには様々なメリットがあります。しかし、すべてのシステムをマイクロサービス化すべきかと言うと、必ずしもそうではありません。「Microservices」の共同執筆者であるMartin Fowlerは、「MicroservicePremium」において、「モノリスでは管理しきれないほど複雑なシステムでない場合は、マイクロサービスを検討する必要はない」と述べています。


図11:MicroservicePremium

とはいえ、従来のモノリスでは開発・運用ともに負荷が大きく、遠からずスケールの限界が見えてくるのも事実です。大規模なシステムであれば、どこかのタイミングでアーキテクチャを見直して、マイクロサービスに移行するという判断を下す必要は出てくるのではないでしょうか。

次回

次回については、マイクロサービスの課題として挙げた、パフォーマンスやデータ管理の面で有効なデザインパターンについて、ご紹介して行きたいと思います。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。