サービスディスカバリ

マイクロサービスが他のサービスのネットワーク位置を動的に発見する仕組み

マイクロサービスインフラ

サービスディスカバリとは

サービスディスカバリは、マイクロサービスが他のサービスのネットワーク位置 (IP アドレス、ポート) を動的に発見する仕組みである。コンテナサーバーレスでは IP が動的に変わるため、ハードコードできない。

クライアントサイド vs サーバーサイド

方式の分かれ目は 1 点しかない。宛先の候補から実際に呼ぶ 1 つを選ぶのが呼び出し元か、経路上の中継役かである。

方式宛先を選ぶ主体引き換えに払うもの
クライアントサイド呼び出し元。候補の一覧を受け取り、負荷分散も自分で行う言語ごとにクライアント側の実装が必要で、候補の一覧をアプリが抱えるConsul, Eureka
サーバーサイド経路上の中継役。呼び出し元は固定の宛先だけを知る通信が必ず中継役を通り、そこが遅延の要因にも障害の起点にもなるALB, API Gateway

DNS ベースかレジストリベースかは、この 2 方式とは別の軸、つまり候補の一覧をどう渡すかの違いである。DNS ベース (Cloud Map、Route 53) は名前解決の応答としてレコードを返すため専用のクライアント実装が要らない代わりに、応答に付いた TTL の間は古い候補が使われ続ける。レジストリベース (Consul、Eureka) は専用の API で一覧を取り、変化を購読して反映できる分だけ入れ替えへの追従が速い。

サーバーレスでのサービスディスカバリ

Lambda を中心に組む場合、レジストリを自前で用意する場面はほとんど無くなる。呼び出し先が IP ではなくサービス側の名前 (API のホスト名、テーブル名、キュー URL) で表され、その名前は配置し直しても変わらないためである。宛先の解決は各サービスの側が受け持ち、アプリが持つのは名前だけになる。

Lambda A → API Gateway の URL → Lambda B
Lambda A → DynamoDB のテーブル名 → DynamoDB
Lambda A → SQS のキュー URL → SQS

ECS でのサービスディスカバリ

ECS では Cloud Map による DNS ベースの自動登録と、ALB のパスベースルーティングの 2 つが基本になる。タスクが起動すると Cloud Map の名前空間にインスタンスとして登録され、order-service.myapp.local のような名前で解決できる。停止したタスクは登録から外れるので、呼び出し元は個々の IP を知らずに済む。

2026 年 8 月時点では ECS Service Connect も選べる。タスクごとに置かれたプロキシが通信を仲介する方式で、名前空間内の短い名前で相互に呼び出せるようにしつつ、接続の成否や遅延をサービス横断で同じ形の指標として取り出せる。宛先の選択はプロキシがラウンドロビンと外れ値検出で行うため、VPC の DNS 設定に依存しない点が、Cloud Map の DNS 名を呼び出し元が直接引く形との違いになる。App Mesh によるサービスメッシュも同じ用途に使えたが、App Mesh は 2026 年時点で新規の受付を終了し、2026 年 9 月 30 日にサポート終了が予定されているため、これから選ぶ方法には含めない。

CloudFormation の参照

テンプレートで作った資源の名前や URL は、!Ref!GetAtt で参照して関数の環境変数へ渡せる。値がデプロイのたびに実物から埋め込まれるため、宛先を人がコードに書き写す余地が無くなる。

# CloudFormation の !Ref と !GetAtt がサービスディスカバリの役割
OrderFunction:
  Properties:
    Environment:
      Variables:
        TABLE_NAME: !Ref OrdersTable        # テーブル名
        QUEUE_URL: !Ref NotificationQueue    # キュー URL
        BUCKET_NAME: !Ref AssetBucket        # バケット名

サーバーレスでは CloudFormation の参照が最もシンプルなサービスディスカバリ。

ヘルスチェック

不健全なインスタンスを名前解決の結果から外せて初めて、サービスディスカバリは使い物になる。Cloud Map の設定は 2 通りあり、どちらか一方しか指定できない。

# Cloud Map 自身が対象を監視する (インターネット経由で到達できる資源が対象)
Service:
  Properties:
    HealthCheckConfig:
      Type: HTTP
      ResourcePath: /health
# 判定を外部の監視側に委ねる (VPC 内の資源はこちら)
Service:
  Properties:
    HealthCheckCustomConfig:
      FailureThreshold: 1

後者では Cloud Map は資源に接続して確かめることをせず、外部から送られた状態更新の要求 (UpdateInstanceCustomHealthStatus) の最新値を記録するだけである。不健全と報告されてから約 30 秒のあいだに健全へ戻す要求が届かなければ、そのインスタンスへのルーティングが止まる。2026 年 8 月時点の API リファレンスでは、この設定の FailureThreshold は廃止扱いで常に 1 に固定されており、大きい値を書いても猶予は伸びない。監視の主体が外にあるということは、監視側が落ちたまま報告を止めた場合、Cloud Map からは健全なままに見え続けるということでもある。

つまずきやすい点

古い宛先を掴み続ける事故は、レジストリ側が正しく更新されていても起きる。DNS ベースでは TTL の間はリゾルバやアプリが前の応答を再利用し、実行環境や言語ランタイムが独自に名前解決の結果を保持していれば TTL より長く残ることもある。タスクの入れ替えが速い環境では、TTL を短くするだけでは足りず、接続の失敗を検知して名前解決からやり直す経路をアプリ側に用意しておく必要がある (DNSロードバランシング)。

この記事は役に立ちましたか?

関連用語

関連する記事