マイクロサービスの構築:マイクロサービスアーキテクチャにおけるプロセス間通信

NGINX | 2015年7月24日

編集者 – 全7回の記事シリーズが完結しました:

  1. マイクロサービス入門
  2. マイクロサービスの構築:APIゲートウェイの使用
  3. マイクロサービスの構築:マイクロサービスアーキテクチャにおけるプロセス間通信(本記事)
  4. マイクロサービスアーキテクチャにおけるサービスディスカバリ
  5. マイクロサービス向けイベント駆動型データ管理
  6. マイクロサービスのデプロイ戦略の選択
  7. モノリスからマイクロサービスへのリファクタリング

一連の記事に加え、NGINX Plusを使用したマイクロサービスの実装に関する情報をまとめた電子書籍「Microservices: From Design to Deployment」もダウンロードできます。また、新しい「Microservices Solutionsページ」もご覧ください。

本稿は、マイクロサービスアーキテクチャを使用したアプリケーション構築について解説するシリーズの第3回です。第1回では、マイクロサービスアーキテクチャパターンを紹介し、モノリシックアーキテクチャパターンと比較したうえで、マイクロサービスを使用するメリットとデメリットについて説明しています。第2回では、アプリケーションのクライアントが、API Gatewayと呼ばれる仲介機能を介してマイクロサービスと通信する仕組みについて説明しています。本稿では、システム内のサービスが相互に通信する仕組みを見ていきます。第4回では、これと密接に関連するサービスディスカバリの問題について解説します。

はじめに

モノリシックアプリケーションでは、コンポーネント同士がプログラミング言語レベルのメソッド呼び出しや関数呼び出しを介して相互に呼び出します。一方、マイクロサービスベースのアプリケーションは、複数のマシン上で稼働する分散システムです。通常、各サービスインスタンスは1つのプロセスとして動作します。そのため、次の図に示すように、サービス間のやり取りにはプロセス間通信(IPC)の仕組みが必要です。


マイクロサービスアプリケーションでは、サービス間の通信にプロセス間通信(IPC)メカニズムが必要です(モノリシックアプリケーションのモジュールはルーチンを呼び出せます)

具体的なIPC技術については後ほど説明しますが、まずは設計上のさまざまな課題を見ていきましょう。

インタラクションの形式

サービスのIPCメカニズムを選択する際は、まずサービス間のやり取りについて検討するとよいでしょう。クライアント⇔サービス間のやり取りには、さまざまなスタイルがあります。これらは2つの観点で分類できます。1つ目の観点は、やり取りが1対1か1対多かという点です。

  • 1対1 – 各クライアントリクエストは、必ず1つのサービスインスタンスによって処理されます。
  • 1対多 – 各リクエストは複数のサービスインスタンスによって処理されます。

2つ目の観点は、インタラクションが同期か非同期かです。

  • 同期型 – クライアントはサービスからの迅速な応答を期待し、応答を待つ間、処理をブロックすることもあります。
  • 非同期 – クライアントは応答を待つ間もブロックされず、応答がある場合でも、必ずしもすぐに送信されるとは限りません。

次の表に、さまざまなインタラクション形式を示します。

 1対11対多
同期リクエスト/レスポンス — 
非同期通知パブリッシュ/サブスクライブ
リクエスト/非同期レスポンスパブリッシュ/非同期レスポンス

1対1のインタラクションには、次の種類があります。

  • リクエスト/レスポンス – クライアントがサービスにリクエストを送信し、レスポンスを待ちます。クライアントは、レスポンスが適時に返されることを想定しています。スレッドベースのアプリケーションでは、リクエストを送信したスレッドが待機中にブロックされることもあります。
  • 通知(別名:一方向リクエスト)– クライアントはサービスにリクエストを送信しますが、応答は想定されておらず、送信もされません。
  • リクエスト/非同期レスポンス – クライアントがサービスにリクエストを送信すると、サービスは非同期で応答します。クライアントは応答を待つ間も処理をブロックせず、応答がしばらく届かない可能性を前提として設計されています。

1対多のインタラクションには、次の種類があります。

  • パブリッシュ/サブスクライブ – クライアントが通知メッセージをパブリッシュし、そのメッセージを対象とする0個以上のサービスが受信します。
  • パブリッシュ/非同期応答 – クライアントがリクエストメッセージをパブリッシュし、対象のサービスからの応答を一定時間待機します。

通常、各サービスでは、これらのインタラクションスタイルを組み合わせて使用します。単一のIPCメカニズムで十分なサービスもあれば、複数のIPCメカニズムを組み合わせる必要があるサービスもあります。次の図は、ユーザーが配車をリクエストした際に、配車アプリケーション内のサービスがどのように連携する可能性があるかを示しています。


各サービスでは、通知、リクエスト/レスポンス、パブリッシュ/サブスクライブを組み合わせて使用します。たとえば、乗客のスマートフォンは、配車を依頼するためにTrip Managementサービスへ通知を送信します。Trip Managementサービスは、リクエスト/レスポンスを使用してPassenger Serviceを呼び出し、乗客のアカウントが有効であることを確認します。その後、Trip Managementサービスはトリップを作成し、パブリッシュ/サブスクライブを使用してDispatcherなどの他のサービスに通知します。Dispatcherは、対応可能なドライバーを検索します。

ここまでインタラクションスタイルについて見てきました。次に、APIの定義方法を見ていきましょう。

APIの定義

サービスのAPIは、サービスとそのクライアント間の契約です。どのIPCメカニズムを選択する場合でも、何らかのインターフェース定義言語(IDL)を使用して、サービスのAPIを正確に定義することが重要です。サービスの定義にAPIファーストのアプローチを採用することには、十分な根拠があります。サービスの開発では、まずインターフェース定義を作成し、クライアント開発者とレビューします。API定義を繰り返し検討した後で、初めてサービスを実装します。このように事前に設計することで、クライアントのニーズを満たすサービスを構築できる可能性が高まります。

この記事で後述するように、API定義の内容は、使用するIPCメカニズムによって異なります。メッセージングを使用する場合、APIはメッセージチャネルとメッセージタイプで構成されます。HTTPを使用する場合、APIはURLとリクエストおよびレスポンスの形式で構成されます。後ほど、いくつかのIDLについて詳しく説明します。

APIの進化

サービスのAPIは、時間の経過とともに必ず変化します。モノリシックアプリケーションでは通常、APIを変更し、すべての呼び出し元を更新するのは容易です。一方、マイクロサービスベースのアプリケーションでは、APIの利用側がすべて同じアプリケーション内の別のサービスであっても、はるかに困難です。通常、すべてのクライアントにサービスと足並みをそろえてアップグレードするよう強制することはできません。また、サービスの新しいバージョンを段階的にデプロイすることが多いため、サービスの新旧バージョンが同時に稼働することになります。こうした問題に対処するための戦略を策定することが重要です。

APIの変更への対応方法は、変更の規模によって異なります。変更の中には軽微で、以前のバージョンとの後方互換性を維持できるものもあります。たとえば、リクエストやレスポンスに属性を追加する場合などです。クライアントとサービスは、堅牢性原則に従うよう設計することが適切です。古いAPIを使用するクライアントも、新しいバージョンのサービスで引き続き動作する必要があります。サービスは不足しているリクエスト属性にデフォルト値を設定し、クライアントは追加のレスポンス属性を無視します。APIを容易に進化させられるIPCメカニズムとメッセージ形式を使用することが重要です。

ただし、APIに互換性のない大幅な変更を加えなければならない場合もあります。クライアントに即時のアップグレードを強制することはできないため、サービスは一定期間、旧バージョンのAPIをサポートする必要があります。RESTなどのHTTPベースのメカニズムを使用している場合は、URLにバージョン番号を埋め込む方法があります。各サービスインスタンスで複数のバージョンを同時に処理することも、特定のバージョンを処理するインスタンスをバージョンごとにデプロイすることもできます。

部分的な障害への対処

「API Gatewayに関する前回の記事<.htmla>」で説明したように、分散システムには部分障害のリスクが常に存在します。クライアントとサービスは別々のプロセスであるため、サービスがクライアントからのリクエストに適時に応答できない場合があります。障害やメンテナンスによってサービスが停止している可能性もあります。また、サービスが過負荷になり、リクエストへの応答が極端に遅くなることもあります。

たとえば、同記事の「商品詳細シナリオ」について考えてみましょう。Recommendation Serviceが応答しない状況を想定します。単純なクライアント実装では、応答を待ち続けて無期限にブロックされる可能性があります。その結果、ユーザーエクスペリエンスが低下するだけでなく、多くのアプリケーションではスレッドなどの貴重なリソースが消費されます。最終的には、次の図に示すように、ランタイムがスレッドを使い果たして応答しなくなります。


マイクロサービスアプリは部分的な障害に対処できるよう設計する必要があります。そうしないと、応答しないサービスを待つクライアントがブロックされ、ランタイムのスレッドが枯渇する可能性があります

この問題を防ぐには、部分的な障害に対処できるようにサービスを設計することが不可欠です。

参考にすべき優れたアプローチとして、Netflixが説明しているものがあります。部分的な障害に対処するための戦略には、次のものがあります。

  • ネットワークタイムアウト – 応答を待機する際は、無期限にブロックせず、必ずタイムアウトを設定します。タイムアウトを使用することで、リソースが無期限に占有されるのを防げます。
  • 未処理リクエスト数の制限 – クライアントが特定のサービスに対して保持できる未処理リクエスト数に上限を設定します。上限に達している場合、追加のリクエストを行っても意味がない可能性が高いため、その試行は直ちに失敗させる必要があります。
  • サーキットブレーカーパターン – 成功したリクエストと失敗したリクエストの数を追跡します。エラー率が設定済みのしきい値を超えた場合は、サーキットブレーカーを作動させ、それ以降の試行が直ちに失敗するようにします。多数のリクエストが失敗している場合、サービスが利用できず、リクエストを送信しても意味がないことを示唆しています。タイムアウト期間の経過後、クライアントは再試行し、成功した場合はサーキットブレーカーを閉じます。
  • フォールバックを提供する – リクエストが失敗した場合に、フォールバックロジックを実行します。たとえば、キャッシュされたデータや、空のレコメンデーションセットなどのデフォルト値を返します。

Netflix Hystrixは、これらをはじめとするパターンを実装するオープンソースライブラリです。JVMを使用している場合は、Hystrixの使用をぜひ検討してください。JVM以外の環境で実行している場合は、同等のライブラリを使用してください。

IPCテクノロジー

IPC技術には、さまざまな選択肢があります。サービスでは、HTTPベースのRESTやThriftなど、同期型の要求/応答ベースの通信メカニズムを使用できます。また、AMQPやSTOMPなど、非同期型のメッセージベースの通信メカニズムも使用できます。メッセージ形式にもさまざまな種類があります。サービスでは、JSONやXMLなど、人が読めるテキストベースの形式を使用できます。また、AvroやProtocol Buffersなど、より効率的なバイナリ形式も使用できます。同期型IPCメカニズムについては後ほど取り上げますが、まずは非同期型IPCメカニズムについて説明します。

非同期メッセージベース通信

メッセージングを使用する場合、プロセスはメッセージを非同期に交換して通信します。クライアントは、サービスにメッセージを送信してリクエストを行います。サービスからの応答が想定されている場合、サービスは別のメッセージをクライアントに返します。通信は非同期であるため、クライアントは応答を待つ間もブロックされません。代わりに、応答がすぐには届かないことを前提としてクライアントを実装します。

A メッセージは、ヘッダー(送信者などのメタデータ)とメッセージ本文で構成されます。メッセージはチャネルを介して交換されます。任意の数のプロデューサーがチャネルにメッセージを送信できます。同様に、任意の数のコンシューマーがチャネルからメッセージを受信できます。チャネルには、ポイントツーポイントとパブリッシュ/サブスクライブの2種類があります。ポイントツーポイントチャネルは、そのチャネルから読み取るコンシューマーのうち、厳密に1つにメッセージを配信します。サービスは、前述の1対1のインタラクション形式にポイントツーポイントチャネルを使用します。パブリッシュ/サブスクライブチャネルは、接続されているすべてのコンシューマーに各メッセージを配信します。サービスは、前述の1対多のインタラクション形式にパブリッシュ/サブスクライブチャネルを使用します。

次の図は、タクシー配車アプリケーションでパブリッシュ/サブスクライブチャネルを使用する方法の一例を示しています。


タクシー配車アプリケーションのマイクロサービスは、ディスパッチャーと他のサービス間の通信にパブリッシュ/サブスクライブチャネルを使用

Trip Managementサービスは、Trip Createdメッセージをパブリッシュ/サブスクライブチャネルに書き込むことで、新しいTripについてDispatcherなどの関連サービスに通知します。Dispatcherは対応可能なドライバーを見つけ、Driver Proposedメッセージをパブリッシュ/サブスクライブチャネルに書き込むことで、他のサービスに通知します。

選択できるメッセージングシステムは数多くあります。さまざまなプログラミング言語をサポートするものを選ぶことを推奨します。AMQPやSTOMPなどの標準プロトコルをサポートするメッセージングシステムもあれば、独自仕様ながら文書化されたプロトコルを採用するものもあります。オープンソースのメッセージングシステムも数多くあり、たとえばRabbitMQ、Apache Kafka、Apache ActiveMQ、NSQなどがあります。大まかに言えば、いずれも何らかの形式のメッセージとチャネルをサポートし、信頼性、高パフォーマンス、スケーラビリティの実現を目指しています。ただし、各ブローカーのメッセージングモデルには、細部に大きな違いがあります。

メッセージングの利用には、次のような多くの利点があります。

  • クライアントをサービスから分離 – クライアントは、適切なチャネルにメッセージを送信するだけでリクエストを行えます。クライアントはサービスインスタンスを一切認識しないため、サービスインスタンスの場所を特定するために検出メカニズムを使用する必要はありません。
  • メッセージのバッファリング – HTTPなどの同期型リクエスト/レスポンスプロトコルでは、通信中はクライアントとサービスの両方が利用可能でなければなりません。一方、メッセージブローカーは、チャネルに書き込まれたメッセージをコンシューマーが処理できるようになるまでキューに保持します。そのため、たとえば注文処理システムの動作が遅い場合や利用できない場合でも、オンラインストアは顧客からの注文を受け付けることができます。注文メッセージはそのままキューに蓄積されます。
  • 柔軟なクライアントとサービス間のやり取り – メッセージングは、前述したすべてのやり取りの形式をサポートします。
  • 明示的なプロセス間通信 – RPCベースのメカニズムは、リモートサービスの呼び出しをローカルサービスの呼び出しと同じように見せようとします。しかし、物理法則や部分的な障害が発生する可能性があるため、実際には両者は大きく異なります。メッセージングでは、こうした違いが明確になるため、開発者が誤った安心感を抱くことを防げます。

ただし、メッセージングの使用には、次のようなデメリットもあります。

  • 運用の複雑さの増大 – メッセージングシステムは、インストール、設定、運用が必要なシステムコンポーネントをさらに増やします。メッセージブローカーには高可用性が不可欠です。そうでなければ、システムの信頼性に影響が及びます。
  • リクエスト/レスポンスベースのやり取りを実装する際の複雑さ – リクエスト/レスポンス形式のやり取りを実装するには、一定の作業が必要です。各リクエストメッセージには、応答チャネル識別子と相関識別子を含める必要があります。サービスは、相関IDを含むレスポンスメッセージを応答チャネルに書き込みます。クライアントは相関IDを使用して、レスポンスとリクエストを対応付けます。多くの場合、リクエスト/レスポンスを直接サポートするIPCメカニズムを使用する方が簡単です。

メッセージングベースのIPCについて確認したところで、次にリクエスト/レスポンスベースのIPCを見ていきます。

同期型リクエスト/レスポンスIPC

同期型のリクエスト/レスポンス方式のIPCメカニズムを使用する場合、クライアントはサービスにリクエストを送信します。サービスはリクエストを処理し、レスポンスを返します。多くのクライアントでは、リクエストを行ったスレッドはレスポンスを待つ間ブロックされます。一方、FuturesやRx Observablesでカプセル化された、非同期のイベント駆動型クライアントコードを使用する場合もあります。ただし、メッセージングを使用する場合とは異なり、クライアントはレスポンスが適時に届くことを前提とします。選択できるプロトコルは数多くあります。代表的なものとしてRESTとThriftがあります。まずはRESTについて見ていきます。

REST

現在では、APIをRESTfulスタイルで開発することが一般的です。RESTは、(ほぼ常に)HTTPを使用するIPCメカニズムです。RESTの主要な概念はリソースです。通常、リソースはCustomerやProductなどのビジネスオブジェクト、またはビジネスオブジェクトのコレクションを表します。RESTでは、URLで参照されるリソースを操作するためにHTTPメソッドを使用します。たとえば、GETリクエストはリソースの表現を返します。その形式はXMLドキュメントやJSONオブジェクトなどです。POSTリクエストは新しいリソースを作成し、PUTリクエストはリソースを更新します。RESTの考案者であるRoy Fieldingの言葉を引用します。

「RESTは、一連のアーキテクチャ上の制約を提供します。これらを一体として適用することで、コンポーネント間のインタラクションのスケーラビリティ、インターフェースの汎用性、コンポーネントの独立したデプロイ、さらにインタラクションのレイテンシー低減、セキュリティの適用、レガシーシステムのカプセル化を実現する中間コンポーネントが重視されます。」

次の図は、タクシー配車アプリケーションでRESTを使用する方法の一例を示しています。


マイクロサービスベースの配車アプリで、乗客のスマートフォンがPOSTリクエストを送信し、配車管理マイクロサービスがそのリクエストをGETリクエストに変換して乗客確認マイクロサービスに送信する

乗客のスマートフォンは、Trip ManagementサービスのPOSTリクエストを/tripsリソースに送信して、配車をリクエストします。このサービスは、乗客に関する情報を取得するため、Passenger ManagementサービスにGETリクエストを送信して処理します。乗客に配車をリクエストする権限があることを確認すると、Trip Managementサービスは配車を作成し、スマートフォンに201レスポンスを返します。

多くの開発者は、自らのHTTPベースのAPIがRESTfulであると主張しています。しかし、Fieldingがこの「ブログ記事」で説明しているように、実際にはすべてがRESTfulであるとは限りません。Leonard Richardson(同名ですが、Fieldingとの関係はありません)は、非常に有用な「REST成熟度モデル」を定義しており、次のレベルで構成されています。

  • レベル0 – レベル0 APIのクライアントは、唯一のURLエンドポイントにHTTP POSTリクエストを送信してサービスを呼び出します。各リクエストでは、実行するアクション、アクションの対象(ビジネスオブジェクトなど)、およびパラメーターを指定します。
  • レベル1 – レベル1 APIは、リソースという概念をサポートします。リソースに対してアクションを実行するには、クライアントは、実行するアクションとパラメーターを指定した「POST」リクエストを送信します。
  • レベル2 – レベル2 APIでは、HTTP動詞を使用してアクションを実行します。取得には「GET」、作成には「POST」、更新には「PUT」を使用します。リクエストにクエリパラメーターや本文がある場合は、そこでアクションのパラメーターを指定します。これにより、サービスは「GET」リクエストのキャッシュなどのWebインフラストラクチャを活用できます。
  • レベル3 – レベル3 APIの設計は、ひどい名前のHATEOAS(Hypertext As The Engine Of Application State)原則に基づいています。基本的な考え方は、GETリクエストによって返されるリソース表現に、そのリソースに対して許可されているアクションを実行するためのリンクを含めるというものです。たとえば、クライアントは、注文を取得するために送信したGETリクエストへの応答として返されたOrder表現内のリンクを使用して、注文をキャンセルできます。HATEOASの利点として、クライアントコードにURLをハードコーディングする必要がなくなることが挙げられます。また、リソース表現には許可されているアクションへのリンクが含まれるため、クライアントはリソースの現在の状態で実行可能なアクションを推測する必要がありません。

HTTPベースのプロトコルを使用することには、次のような多くのメリットがあります。

  • HTTPはシンプルで広く使われています。
  • HTTP APIは、Postmanなどの拡張機能を使用してブラウザー内からテストすることも、curlを使用してコマンドラインからテストすることもできます(JSONなどのテキスト形式が使用されていることが前提です)。
  • リクエスト/レスポンス形式の通信を直接サポートします。
  • もちろん、HTTPはファイアウォールとの親和性に優れています。
  • 中間ブローカーが不要なため、システムアーキテクチャが簡素化されます。

HTTPの使用には、いくつかの欠点があります。

  • 直接サポートされるのは、リクエスト/レスポンス形式の通信のみです。HTTPを通知に使用することもできますが、サーバーは必ずHTTPレスポンスを送信する必要があります。
  • クライアントとサービスは、メッセージをバッファリングする仲介者を介さずに直接通信するため、通信中は両方が稼働している必要があります。
  • クライアントは、各サービスインスタンスの場所(URL)を把握している必要があります。API Gatewayに関する前回の記事で説明したように、これは最新のアプリケーションでは容易に解決できない問題です。クライアントは、サービスインスタンスを特定するためにサービスディスカバリメカニズムを使用する必要があります。

最近、開発者コミュニティでは、RESTful API向けインターフェース定義言語の価値が再認識されています。選択肢はいくつかあり、たとえばRAMLやSwaggerがあります。SwaggerなどのIDLでは、リクエストメッセージとレスポンスメッセージの形式を定義できます。一方、RAMLなどでは、JSON Schemaのような別の仕様を使用する必要があります。IDLには、APIを記述する機能に加え、通常、インターフェース定義からクライアントスタブとサーバースケルトンを生成するツールも用意されています。

Thrift

Apache Thriftは、RESTに代わる興味深い選択肢です。複数の言語に対応するRPCクライアントとサーバーを作成するためのフレームワークです。Thriftは、APIを定義するためのC言語形式のIDLを提供します。Thriftコンパイラを使用して、クライアント側のスタブとサーバー側のスケルトンを生成します。このコンパイラは、C++、Java、Python、PHP、Ruby、Erlang、Node.jsなど、さまざまな言語のコードを生成します。

Thriftインターフェースは、1つ以上のサービスで構成されます。サービス定義はJavaインターフェースに相当し、強く型付けされたメソッドの集合です。Thriftメソッドは、値(voidの場合もあります)を返すか、one-wayとして定義できます。値を返すメソッドは、リクエスト/レスポンス形式の通信を実装します。クライアントはレスポンスを待機し、例外をスローする場合があります。one-wayメソッドは通知形式の通信に対応し、サーバーはレスポンスを送信しません。

Thriftは、JSON、バイナリ、コンパクトバイナリなど、さまざまなメッセージ形式をサポートしています。バイナリはデコードが高速なため、JSONよりも効率的です。また、その名が示すとおり、コンパクトバイナリは容量効率に優れた形式です。もちろん、JSONは人にとって読みやすく、ブラウザでも扱いやすい形式です。Thriftでは、raw TCPやHTTPなどのトランスポートプロトコルも選択できます。raw TCPはHTTPよりも効率的である可能性が高い一方、HTTPはファイアウォールやブラウザとの親和性が高く、人にも扱いやすいプロトコルです。

メッセージ形式

HTTPとThriftについて確認したところで、次にメッセージ形式について考えてみましょう。メッセージングシステムまたはRESTを使用する場合は、メッセージ形式を選択できます。一方、Thriftなどの他のIPCメカニズムでは、サポートされるメッセージ形式が少数、場合によっては1つだけのこともあります。いずれの場合も、複数の言語に対応したメッセージ形式を使用することが重要です。現在は単一の言語でマイクロサービスを作成していても、将来的には他の言語も使用する可能性が高いためです。

メッセージ形式には、主にテキスト形式とバイナリ形式の2種類があります。テキストベースの形式には、JSONやXMLなどがあります。これらの形式には、人間が読めるだけでなく、自己記述的であるという利点があります。JSONでは、オブジェクトの属性は名前と値のペアの集合として表されます。同様に、XMLでは、属性は名前付きの要素と値で表されます。そのため、メッセージのコンシューマーは、必要な値だけを取り出し、残りを無視できます。したがって、メッセージ形式に軽微な変更を加えても、後方互換性を容易に維持できます。

XMLドキュメントの構造は、XMLスキーマによって定義されます。やがて開発者コミュニティでは、JSONにも同様の仕組みが必要だと認識されるようになりました。その選択肢の1つが、JSON Schemaを単独で、またはSwaggerなどのIDLの一部として使用することです。

テキストベースのメッセージ形式には、メッセージが冗長になりがちという欠点があり、特にXMLで顕著です。メッセージが自己記述型であるため、各メッセージには属性値だけでなく属性名も含まれます。また、テキストの解析に伴うオーバーヘッドも欠点です。そのため、バイナリ形式の使用を検討するとよいでしょう。

バイナリ形式には複数の選択肢があります。Thrift RPCを使用している場合は、バイナリThriftを使用できます。メッセージ形式を選択できる場合、一般的な選択肢としては、Protocol BuffersやApache Avroがあります。どちらの形式も、メッセージの構造を定義するための型付きIDLを提供します。ただし、Protocol Buffersがタグ付きフィールドを使用するのに対し、Avroのコンシューマーがメッセージを解釈するにはスキーマを把握している必要があります。そのため、Protocol BuffersはAvroよりもAPIを容易に進化させることができます。こちらのブログ記事では、Thrift、Protocol Buffers、Avroが詳しく比較されています。

まとめ

マイクロサービス間の通信には、プロセス間通信メカニズムが必要です。サービス間の通信方法を設計する際は、サービス同士の連携方法、各サービスのAPIの定義方法、APIの進化方法、部分的な障害への対処方法など、さまざまな課題を検討する必要があります。マイクロサービスで使用できるIPCメカニズムには、非同期メッセージングと同期リクエスト/レスポンスの2種類があります。シリーズの次の記事では、マイクロサービスアーキテクチャにおけるサービスディスカバリの課題について説明します。

編集者 – 全7回の記事シリーズが完結しました:

  1. マイクロサービス入門
  2. マイクロサービスの構築:APIゲートウェイの使用
  3. マイクロサービスの構築:マイクロサービスアーキテクチャにおけるプロセス間通信(本記事)
  4. マイクロサービスアーキテクチャにおけるサービスディスカバリ
  5. マイクロサービス向けイベント駆動型データ管理
  6. マイクロサービスのデプロイ戦略の選択
  7. モノリスからマイクロサービスへのリファクタリング

一連の記事に加え、NGINX Plusを使用したマイクロサービスの実装に関する情報をまとめた電子書籍「マイクロサービス:設計からデプロイまで」もダウンロードできます。

ゲストブロガーのChris Richardson氏は、初期のAmazon EC2向けJava PaaS(Platform as a Service)である、当初の「CloudFoundry.com」の創設者です。現在は、アプリケーションの開発およびデプロイ方法の改善に向けて、組織にコンサルティングを提供しています。また、マイクロサービスについて「http://microservices.io」で定期的にブログを執筆しています。


共有

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります