SA.01.2 柔軟性を高めるアーキテクチャパターン (重要度: 5)
ホゲホゲ
ふがふが
マイクロサービスアーキテクチャを用いた際のメリット・デメリット
マイクロサービスアーキテクチャは、2014年3月に公開された、この概念を広めた著名なブログ「MicroServices(https://martinfowler.com/articles/microservices.html)」によれば、
つまり、マイクロサービス・アーキテクチャ・スタイル[1]は、1つのアプリケーションを小さなサービスの集合として開発するアプローチであり、それぞれが独自のプロセスで実行され、軽量なメカニズム(多くの場合、HTTPリソースAPI)で通信する。これらのサービスはビジネス機能を中心に構築され、完全に自動化されたデプロイメント・マシーンによって独立してデプロイされる。これらのサービスは、異なるプログラミング言語で記述され、異なるデータストレージ技術を使用することができる。(筆者訳)
とのことである。つまり、マイクロサービスアーキテクチャは独立に動くマイクロサービスを通信によって結合することによって構成されるアーキテクチャである。この利点を、独立した技術選択、スケーリング、デプロイの面から説明する。
はじめに、マイクロサービスアーキテクチャはマイクロサービス間で開発言語を合わせる必要がないため、それぞれのマイクロサービスにとって最適な開発言語を選択することができ、開発やメンテナンス等の容易さに貢献する。
次に、マイクロサービスアーキテクチャはマイクロサービス間を通信によって結合するため、同一のマイクロサービスのプロセスを複数実行することによって容易にスケーリングが行える。
最後に、マイクロサービスは各々で独立しているので、メンテナンスや開発計画をマイクロサービスごとに独立して考えられるようになる。さらに、それぞれの規模も小さいことから、コストの圧縮も見込むことができる。
反対に、マイクロサービスのデメリットとしては、サービス全体で見たときの構造の複雑さ、マイクロサービス間で通信を多用することによるパフォーマンスの問題、全体的に見たときのコストなどが挙げられる。
参考:
https://knowledge.sakura.ad.jp/20167/
マイクロサービスで良く用いられるサービス間通信
同期通信
- REST (OpenAPI):
RESTは、Representational State Transferの略で、Webアプリケーションのために設計されたアーキテクチャスタイルです。RESTfulなAPIは、リソースの表現とその操作方法を定義するためにHTTPプロトコルを使用します。OpenAPIは、RESTfulなAPIをドキュメント化するための仕様であり、APIのエンドポイント、リクエスト/レスポンスの形式やパラメータといった詳細な情報を提供します。 - GraphQL:
GraphQLは、Facebookによって開発されたクエリ言語とデータ操作のためのランタイムです。GraphQLでは、クライアントが必要なデータとその形式を明示的に指定するため、過剰または不足なデータの受け渡しを回避できます。また、単一のエンドポイントを介してデータを取得することで、ネットワークのオーバーヘッドを削減できます。GraphQLのクエリは柔軟で強力であり、異なるデータソースからのデータの結合や変換も可能です。 - gRPC/Protocol Buffer:
gRPCは、Googleによって開発された高性能なRPC(Remote Procedure Call)フレームワークです。gRPCでは、Protocol Bufferというバイナリ形式のメッセージングフォーマットを使用して、クライアントとサーバー間で効率的な通信を実現します。Protocol Bufferは、言語やプラットフォームに依存しないデータ定義を提供し、リクエストとレスポンスのデータの直列化と逆直列化を行うため、パフォーマンスの向上を図ります。
RESTfulなAPIは標準的で広く使われており、ドキュメント化やツールサポートに優れています。GraphQLはフロントエンド開発やマイクロサービスアーキテクチャにおいて、クエリの柔軟さとパフォーマンスの向上を提供します。gRPC/Protocol Bufferは高性能なマイクロサービス間の通信に適しており、ソフトウェアエンジニアリングにおける効率とパフォーマンスを向上させます。
非同期通信
- キュー(Queue):
非同期通信において、キューはメッセージキューとして使用されます。送信側(パブリッシャー)はメッセージをキューに追加し、非同期に送信されます。受信側(コンシューマー)はキューからメッセージを取り出し、処理します。キューを介してメッセージを送信することで、送信と受信の両方が非同期に行われます。キューを使用することで、送信側と受信側の処理速度の違いを吸収したり、バッチ処理することができます。 - ストリーム(Stream):
非同期通信において、ストリームはリアルタイムのデータを連続的に送受信するために使用されます。ストリームはパブリッシャーとサブスクライバの間でデータをストリームとして転送し、リアルタイムに処理されます。ストリームは時間経過とともにデータが到着することを想定しており、連続的にデータを処理する機能を提供します。ストリームを使用することで、データの逐次的な処理やリアルタイムのレスポンスが可能になります。 - トピック(Topic):
非同期通信において、トピックはパブサブパターンのメッセージングシステムで使用されます。パブリッシャーはメッセージを特定のトピックに関連付けて配信します。サブスクライバはあるトピックに関心を持ち、そのトピックに対してメッセージを受け取るために登録します。トピックを使用することで、パブリッシャーとサブスクライバは明確なコミュニケーションチャネルを持つことなく、非同期にメッセージをやり取りすることができます。トピックは関心事やカテゴリごとにメッセージを効率的にフィルタリングすることも可能です。
アプリケーション実装からシステム制御機能を分離する設計パターン
サービスプロキシ, サイドカーパターン
- サービスプロキシ(Service Proxy):
サービスプロキシは、クライアントとサーバーの間に位置する中間層のコンポーネントです。クライアントはサービスプロキシに対してリクエストを送信し、サービスプロキシはそれを受け取って適切なサーバーに転送します。サービスプロキシは転送されたリクエストとレスポンスをモニタリングし、必要に応じて変更や追加の処理を行うこともあります。また、セキュリティ機能や負荷分散などの管理も行います。サービスプロキシを使用することで、クライアントとサーバーの間に抽象化されたインターフェースを提供し、柔軟性や拡張性を向上させることができます。 - サイドカーパターン(Sidecar Pattern):
サイドカーパターンは、マイクロサービスアーキテクチャにおいて、各マイクロサービスの機能とは別に、共通の機能を持つサイドカーと呼ばれる別のコンテナを併せて動作させるパターンです。マイクロサービスはそれぞれ独立して開発・デプロイされますが、共通の機能やプロキシ機能を共有するためにサイドカーパターンを使用することがあります。サイドカーは各マイクロサービスから切り離され、それぞれの責務を助ける役割を果たします。例えば、ロギング、メトリクス収集、認証、トラフィック管理などの機能をサイドカーとして実装することで、各マイクロサービスの責務を明確にし、再利用性やメンテナンス性を向上させることができます。
コントロールプレーンとデータプレーンの分離
コントロールプレーンとデータプレーンの分離は、ネットワーキングや分散システムにおいて使用される重要な概念です。
- コントロールプレーン(Control Plane):
コントロールプレーンは、システムの制御や管理に関連する機能を担当します。例えば、ルーティングテーブルの作成や更新、トラフィックの制御、ポリシーの設定などが含まれます。コントロールプレーンは、ネットワーキングやシステム全体の状態や状況を監視し、制御命令を発行します。 - データプレーン(Data Plane):
データプレーンは、実際のデータ処理と通信を担当します。データパケットやリクエストを受け取り、宛先に応じた処理や転送を行います。データプレーンは、コントロールプレーンからの命令やポリシーに従ってアクションを実行します。通常、ネットワーキングやシステムのパフォーマンスの向上に焦点が当てられます。
コントロールプレーンとデータプレーンの分離は、スケーラビリティ、メンテナンス性、柔軟性の向上を可能にします。コントロールプレーンとデータプレーンが分けられることで、ネットワーキングやシステムの機能とパフォーマンスを独立して拡張したり、異なるコンポーネントやシステムとの統合を容易にすることができます。また、障害や負荷の影響も限定的になります。
サービスメッシュ
サービスメッシュは、分散システム内の複数のサービス間の通信を抽象化し、制御するためのネットワーキングのアーキテクチャです。主な目的は、マイクロサービスアーキテクチャにおける可観測性、信頼性、セキュリティの向上です。
サービスメッシュでは、各サービスはサイドカーコンテナ(通常はプロキシ)として知られる別のプロセスとペアになります。サイドカーコンテナは各サービスと切り離された形でデプロイされ、サービス間の通信を扱います。具体的には、サイドカーコンテナはリクエストのルーティングやトラフィックの監視、セキュリティの適用、トランスポートの暗号化などを担当します。
サービスメッシュの利点は、以下のようにまとめることができます:
- 可観測性:サービスメッシュでは、トラフィックのモニタリングやログの収集、メトリクスの収集、トレーシングなどの機能を提供します。これにより、システム内での通信やエラーのトラブルシューティングとデバッグが容易になります。
- セキュリティ:サービスメッシュは、トラフィックの暗号化や認証、アクセスコントロールなど、セキュリティに関連する機能を提供します。これにより、分散されたサービス間の通信が安全に行われます。
- ロードバランシングとトラフィック制御:サービスメッシュは、トラフィックの振り分けや負荷分散、フェイルオーバーなどの機能を提供します。これにより、負荷の分散や可用性の向上が実現できます。
サービスメッシュの実装には、Istio、Linkerd、Consulなどのツールやライブラリが利用されます。これらのツールは、Kubernetesなどのオーケストレーションプラットフォームと統合されることが一般的です。
API ゲートウェイ
API ゲートウェイは、マイクロサービスアーキテクチャ内の異なるサービスやクライアント間の通信を効果的に制御、保護、管理するためのサーバーのエントリーポイントです。API ゲートウェイは、外部のクライアント(モバイルアプリケーション、ウェブアプリケーションなど)とバックエンドのマイクロサービス間の通信を統合し、セキュリティや可観測性などの重要な機能を提供します。
API ゲートウェイの主な役割と利点は次のとおりです:
- ルーティングとトランスフォーメーション:API ゲートウェイは、リクエストの受信先を決定し、必要に応じてリクエストやレスポンスの形式を変換します。また、クライアントに特定のサービスエンドポイントのみ表示されるようなフィルタリング機能も提供します。
- セキュリティと認証:API ゲートウェイは、トラフィックの暗号化や認証、アクセス制御を担当します。認証情報の検証やサービス間のセキュリティトークンの付与など、セキュリティポリシーを実装します。
- ロードバランシングとキャッシング:API ゲートウェイは、トラフィックを複数のバックエンドサービスに均等に分散する負荷分散機能を提供します。また、キャッシュの利用により、負荷軽減と高速化を実現します。
- 監視と分析:API ゲートウェイは、トラフィックの監視、ログの収集、パフォーマンスメトリクスの計測、トラブルシューティングなどの機能を提供します。これにより、システムのパフォーマンスを監視し、問題を特定して解決することができます。
一般的に、API ゲートウェイは反応性の向上、可観測性の高さ、セキュリティの確保などのメリットを提供し、複雑なマイクロサービスアーキテクチャにおいてパフォーマンスとセキュリティを確保するために重要な役割を果たします。
分離される主な機能
以下は、アプリケーション実装から分離されるシステム制御機能の具体例です。
- トラフィック制御:アプリケーションがアクセスするネットワークリソースの管理や負荷分散を行うシステム制御機能です。システム制御機能は、アクセス制限やネットワークトポロジの最適化などを実施し、アプリケーションによるネットワークリソースの乱用やネットワークの過負荷を防ぎます。
- 通信障害の回復:システム制御機能は、通信障害の検出や回復を行います。障害が発生すると、システム制御機能は別の通信経路を探し、トラフィックを切り替えることでアプリケーションの中断やデータの損失を最小限に抑えます。
- 認証:システム制御機能は、アプリケーションの認証を処理し、アクセス権限の管理を行います。これにより、アプリケーションへの不正アクセスやデータベースの悪用など、潜在的なセキュリティリスクを低減することができます。
- トレーシング:システム制御機能は、アプリケーションのトラブルシューティングや監視のためのトレーシング機能を提供します。トレーシング機能により、アプリケーションの実行中の要求や処理時間などの情報を収集し、問題の特定や効率の向上をサポートします。
これらのシステム制御機能はアプリケーションから分離されることで、アプリケーションの実装コードを簡素化し、柔軟性と拡張性を向上させます。また、システム制御機能は複数のアプリケーションに共通して利用されるため、効率的なリソース利用やセキュリティの維持にも貢献します。
イベント駆動とリソース動的確保を組み合わせたデザインパターン
サーバレス技術とは、アプリケーションの実行においてサーバを意識する必要がないというアーキテクチャの考え方です。サーバレスアプリケーションは、サービスプロバイダーがインフラストラクチャの管理を担当し、ユーザーはアプリケーションのロジックに集中することができます。一方、FaaS(Function as a Service)は、サーバレスコンピューティングの一種であり、イベントに応じて単一の関数を実行する形式です。FaaSはサーバレスアーキテクチャの一部になりますが、より特定の形態であると言えます。
例:AWSはサーバレス技術、AWS LambdaはFaaS
FaaSは上述の通りイベント駆動なので、アプリケーションの実行は、特定のトリガーまたはイベントが発生したときにのみトリガーされます。例えば、HTTPリクエストの受信、データベースの変更、メッセージキューの新しいメッセージなどが該当します。イベントが発生していない場合、コードは実行されずに待機状態になります。また、FaaSは、リクエストの数やアプリケーションの負荷に応じて自動的にスケールすることができます。必要な場合にコードを自動的に複数のインスタンスに展開し、処理を並列化することで、スケーラビリティを実現します。これにより、不要なリソースの無駄な使用を避けることができます。
FaaSの一般的な利点には、開発プロセスの簡素化、スケーラビリティの向上、コスト削減、運用オーバーヘッドの削減などが含まれます。しかし、サーバーレスアーキテクチャの特性に基づいた設計と開発の煩雑さも考慮する必要があります。