Service Discoveryとは?
Service Discoveryは、分散システムにおいてサービス同士が自動的に発見し、接続するためのプロセスです。
従来のモノリシックなアプリケーションでは、各コンポーネントは一つのアプリケーションとして結合され、一緒にデプロイされていました。しかし、マイクロサービスアーキテクチャでは、サービスは個別のコンテナや仮想マシンにデプロイされ、そのIPアドレスやポート番号は以下のような理由で動的に変更される可能性があります:
- スケーリング(サービスのインスタンス数を増減させる)
- 障害発生時の自動復旧
- 新バージョンのデプロイ
このような動的な環境で、サービス間の通信を安定して行うためには、Service Discoveryが重要な役割を果たします。
電話帳のような仕組み
Service Discoveryは、私たちが普段使う電話帳に例えることができます:
- 電話帳:サービスレジストリ(利用可能なサービスの一覧を管理)
- 名前:サービス名
- 電話番号:IPアドレスとポート番号
- 最新の連絡先情報:サービスの健康状態
Service Discoveryの主要コンポーネント
サービスレジストリ
サービスレジストリは、利用可能なサービスとそのインスタンスの情報を保存する中央データベースです。以下の情報を管理します:
- サービス名
- インスタンスのIPアドレス
- ポート番号
- 健康状態
- メタデータ(バージョン、環境など)
各サービスは起動時にサービスレジストリに自身を登録し、定期的にヘルスチェック信号(ハートビート)を送信して、自身が正常に動作していることを通知します。
2つのService Discoveryパターン
Service Discoveryには、大きく分けて2つの実装パターンがあります:
- クライアントサイドディスカバリ
- サーバーサイドディスカバリ
1. クライアントサイドディスカバリ
クライアントサイドディスカバリでは、クライアントが直接サービスレジストリに問い合わせを行い、利用可能なサービスインスタンスを発見します。
処理の流れ
- クライアントがサービスレジストリに特定のサービスのインスタンス一覧を要求
- サービスレジストリが利用可能なインスタンスのIPアドレスとポート番号のリストを返却
- クライアントが負荷分散アルゴリズム(ラウンドロビンなど)を使用してインスタンスを選択
- クライアントが選択したインスタンスに直接接続
2. サーバーサイドディスカバリ
サーバーサイドディスカバリでは、クライアントはロードバランサーに対してリクエストを送信し、ロードバランサーが適切なサービスインスタンスにリクエストを転送します。
処理の流れ
- クライアントが既知のアドレス(ロードバランサー)にリクエストを送信
- ロードバランサーがサービスレジストリに問い合わせて利用可能なインスタンスを取得
- ロードバランサーがインスタンスを選択してリクエストを転送
各パターンの比較
クライアントサイドディスカバリ
メリット:
- 負荷分散の制御が細かくできる
- 直接通信によるレイテンシの削減
- 余分なホップがない
デメリット:
- クライアントの実装が複雑になる
- 各言語・フレームワークでのクライアントライブラリが必要(例:JavaならSpring Cloud、Node.jsなら専用のクライアントが必要)
- クライアントがサービスレジストリの可用性に依存
- 言語やフレームワークごとにサービスディスカバリのロジックを実装する必要がある(例:Netflixのケースでは、非JVMクライアント用にPranaというHTTPプロキシベースのアプローチを提供)
サーバーサイドディスカバリ
メリット:
- クライアントの実装がシンプル
- サービス間通信の監視・管理が容易
- 既存のロードバランサーが利用可能
デメリット:
- ロードバランサーが単一障害点になる可能性
- 追加のネットワークホップによるレイテンシ
- インフラの運用コストが増加
実装例
クラウドプラットフォームでの実装
クラウド環境では、サービスディスカバリの機能が組み込まれていることが多いです:
-
AWS Elastic Load Balancer (ELB):
- サーバーサイドディスカバリの代表的な実装
- EC2インスタンスの自動登録・解除
- 内部/外部トラフィックの両方に対応
- Auto Scaling Groupと連携した動的なスケーリング
-
Kubernetes Service Discovery:
- 各ノードで動作するプロキシによるサーバーサイドディスカバリ
- サービス名によるDNSベースの名前解決
- クラスタ内での自動的なサービス検出
- ヘルスチェックと自動復旧
オープンソースの実装
独自のインフラストラクチャを構築する場合、以下のような選択肢があります:
-
Consul (HashiCorp):
- 分散サービスメッシュソリューション
- DNSとHTTP APIの両方をサポート
- 高度な健康診断機能
- サービス設定の集中管理
-
Eureka (Netflix):
- Javaベースのサービスレジストリ
- AWS環境での利用に最適化
- Spring Cloudとの統合
- 注意: 他の言語での利用には追加のクライアントライブラリが必要
-
etcd:
- 分散キーバリューストア
- Kubernetesの基盤技術として使用
- 軽量で高性能
- 一貫性の高いデータストレージ
-
ZooKeeper (Apache):
- 分散コーディネーションサービス
- 高い信頼性と安定性
- 複雑な分散システムでの実績
- 比較的セットアップが複雑
まとめ
Service Discoveryは、マイクロサービスアーキテクチャにおいて重要な役割を果たす仕組みです。実装パターンには大きく分けてクライアントサイドとサーバーサイドの2つがあり、それぞれに特徴があります。
システムの要件や制約に応じて適切なパターンを選択することが重要です:
- 細かい制御が必要な場合 → クライアントサイド
- シンプルさを重視する場合 → サーバーサイド
また、既存のソリューション(Consul、Eureka等)を活用することで、Service Discoveryの実装を効率的に行うことができます。