マイクロサービスにおけるサービス間の通信
2024-07-24最近こちらの書籍でマイクロサービスについて学習しています。今回はそんなマイクロサービスのサービス間の通信について学習したことをアウトプットしていきます。この記事では、マイクロサービス間でのデータのやり取り方法に焦点を当て、特に同期通信と非同期通信の違いやそれぞれの問題点にどのように対応するかを詳しく解説します。これにより、より効率的で堅牢なシステム設計の知識が身につくでしょう。
目次
通信の種類
マイクロサービスのサービス間の通信では大きく分けて2つの種類があります。
- 同期通信 : クライアントはサービスがタイムリーにリクエストを返してくることを想定している
- 非同期通信 : サービス側がタイムリーにリクエストを返してくるとは限らない
同期処理
同期処理では代表例として以下の2つがあります。
- REST
- gRPC
REST
多くの開発者にとって馴染みがあると思います。JSONやXML形式でデータをやり取りします。
gRPC
Googleが開発したプロトコルで、高効率かつ高速な通信が可能です。プロトコルバッファを使用して、効率的にバイナリ形式でデータをやり取りします。
同期通信の問題点とその対応
同期通信ではエラー処理とサービスディスカバリの問題があります。それぞれ詳しくみていきます。
エラー処理
マイクロサービスでは複数のサービスが動作してアプリケーションが動作します。一つのサービスで障害が発生し、利用不可となった時のことを考えます。
同期通信ではクライアントはサービスのレスポンスを待っているので、一つのサービスのレスポンスが来ないことで、システム全体が止まってしまう可能性があります。
対応としては次のようなものが挙げられます。
- ネットワークタイムアウト: タイムアウトの時間を設定しておき、決められた時間内に返信がない場合はエラーを返す
- Circuit breakeパターンを使う: リクエストの成功と失敗の数を数え、エラー率が閾値を超えたら、サーキットブレーカーを動作させる。その後に届いたリクエストについては、すぐに失敗をさせる。ブレーカーがタイムアウトになったら、再びリクエストを試してみて、成功するか確認する。
また考慮すべきこととして、あるリクエストで複数サービスを呼び出す際に、そのリクエストに対して重要なサービスとそれほど重要ではないサービスが存在する場合がります。そんな時は重要なサービスが停止していなければ、重要ではないサービスの結果を待たずして一部の結果だけ返すというような対応も考えられます。
サービスディスカバリ
サービスディスカバリとは使いたいサービスがどこ(IPアドレス)にあるのかわからないを解決するためのアプローチです。
クラウドがメインで使われる現在のシステム開発では、サービスのIPアドレスは動的に変化することが多いです。いざクライアントがサービスを使おうとなった時にどこにリクエストを送れば良いのかを明確にするための仕組みがサービスディスカバリとなっています。
アプリケーションレベルのサービスディスカバリのパターン
まずはアプリケーションレベルのサービスディスカバリのパターンです。このパターンではまずサービスインスタンス(サービス提供者)がサービスレジストリーに自信のIPアドレスを登録します。
サービスを利用するサービスクライアントはサービスレジストリーに対してクエリを送り、サービスインスタンスのリストを入手します。その中の一つにリクエスをお送ります。
プラットフォームが提供するサービスディスカバリのパターン
DockerやKubernetesといったデプロイプラットフォームは組み込みでサービスディスカバリメカニズムを持っています。それを利用するパターンです。
これは3rd party registrationパターンとServer-side discoveryパターンの2つから構成されています。
3rd party registrationではサービスインスタンス自身が登録するのではなく、デプロイプラットフォームの一部になっているレジストラがサービスレジストリに登録を行います。
またServer-side discoveryパターンでは、クライアントがサービスレジストリにリストを問い合わせるのではなく、DNS名にリクエストを送ります。DNS名はリクエストルーターによって解決され、リクエストルーターがサービスレジストリにクエリーを送り、リクエストのロードバランシングを行います。
非同期通信
非同期通信ではメッセージキューを使って実装することが多いです。メッセージブローカーを使ったブローカードとブローカーレスの2種類が存在しています。
ブローカード
ブローカードではサービス間にメッセージを保管するためのメッセージブローカーを用意し、メッセージの送信者や受信者はメッセージブローカーとやり取りをします。
送信者はメッセージブローカに対してメッセージを送信し、メッセージブローカーがメッセージを受信者に送信します。
利点としては以下が挙げられます
- 送信者と受信者はお互いを知る必要がなく疎結合である
- 送信者か受信者が利用不可の場合でも、メッセージはメッセージブローカーによって一時的に保管され、利用可能になった時に送受信されます
欠点としては
- メッセージブローカーのパフォーマンスがボトルネックになるかもしれない
- メッセージブローカーの可用性が極めて高い必要がある
- メッセージブローカーのセットアップやメンテナンスが面倒臭い
ブローカーレス
その名の通りサービス間のブローカーが存在しないパターンです。サービス同士が直接メッセージを交換することができます。
メリットとしては
- 直接メッセージを送れるので、ネットワークトラフィックが軽くなる
- メッセージブローカーのセットアップやメンテナンスが不要
デメリットとしては以下が挙げられます。
- サービスの位置(IPアドレス)を知っておかなければならない
- 送信者と受信者がどちらも利用可能でなければならない
まとめ
この記事では、マイクロサービスにおけるサービス間の通信方法に焦点を当て、同期通信と非同期通信の違い、それぞれの問題点と対処方法について詳しく解説しました。適切な通信手法を選ぶことで、システムの効率と堅牢性を大きく向上させることができます。これからのマイクロサービス開発において、この知識が役立つことを願っています。