ECS Service Connectの新機能「Zone-Awareルーティング」で同一AZ優先のサービス間通信を試してみた

ECS Service Connectの新機能「Zone-Awareルーティング」で同一AZ優先のサービス間通信を試してみた

ECS Service ConnectにZone-Awareルーティングが追加されました。マルチAZ構成のサービス間通信で同一AZ内のエンドポイントを優先的に利用し、クロスAZデータ転送コストとレイテンシの削減が期待できます。実際に動作検証してみました。
2026.07.02

はじめに

2026年7月1日、ECS Service ConnectにZone-Awareルーティング機能が追加されました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/07/ecs-service-connect-zone-aware/

マルチAZ構成のECSサービス間通信において、リクエストを同一AZ内のエンドポイントに優先ルーティングすることで、クロスAZデータ転送コストとレイテンシを削減する機能です。

従来のService Connectはラウンドロビンで全AZに均等分散していたため、マルチAZ構成では必然的にクロスAZ通信が発生していました。マルチAZ構成自体は可用性のために必要ですが、AZ間のデータ転送には追加料金が発生し、レイテンシも増加します。

今回のアップデートにより、デフォルトで同一AZ優先ルーティングが有効になります。

項目 従来の Service Connect Zone-Aware 対応後
ルーティング方式 ラウンドロビン(全AZ均等分散) 同一AZ優先
クロスAZデータ転送 マルチAZ構成で必然的に発生 同一AZ内へ優先ルーティングされるため削減
可用性 AZ障害時は自動フェイルオーバー 同様(容量不足時はクロスAZへ自動再分散)
設定変更 不要(デフォルト有効)
既存サービスへの適用 1回の再デプロイで有効化
追加料金 なし

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-connect-zone-aware-routing.html

仕組み

Zone-Awareルーティングは、Service Connectプロキシ(Envoyサイドカー)のゾーン認識ルーティング機能を利用しています。

動作の流れは以下のとおりです。

  1. エンドポイント検出: プロキシが宛先サービスの全エンドポイントとそのAZ配置を把握する
  2. 同一AZ優先: リクエスト送信元と同じAZのエンドポイントに優先的にルーティングする
  3. 残余容量ルーティング: 同一AZに収まりきらないトラフィックは、他のAZの残余容量に基づいて分配する
  4. フォールバック: 同一AZのエンドポイントが不健全または不足の場合、他のAZに自動的にルーティングする

有効化の閾値条件

Zone-Awareルーティングが有効になるには、宛先サービスのエンドポイント数が 2 × AZ数 以上必要です。

  • 2AZ構成: 最低4エンドポイント
  • 3AZ構成: 最低6エンドポイント

この閾値を下回る場合はAZを考慮しない通常の負荷分散にフォールバックし、エンドポイントが増えると自動的に再有効化されます。これは単一AZへの過負荷を防ぐための仕組みです。

類似概念との比較

同一AZ優先でクロスAZ転送を減らすアプローチは、他のAWSサービスにも存在します。

仕組み 対象通信 同一AZ優先の実現方法
Regional NAT Gateway アウトバウンド通信 ワークロード検出によるAZ親和性(動的)
Service Connect Zone-Aware ECSサービス間通信 Envoyプロキシの重み付け(動的)
ALB クロスゾーン無効化 クライアント→ターゲット ALBノードの分散設定

https://dev.classmethod.jp/articles/aws-nat-gateway-regional-availability/

検証

実際に2AZ構成のECSクラスタでZone-Awareルーティングの動作を確認しました。

検証構成

ECSクラスタ (Service Connect namespace: "test-sc-zone-aware")
├── サービスA (クライアント役, 2タスク)
│   ├── AZ-a: 1タスク (ECS Exec有効)
│   └── AZ-c: 1タスク (ECS Exec有効)
└── サービスB (サーバー役, 4タスク)
    ├── AZ-a: 2タスク
    └── AZ-c: 2タスク

サービスBは自タスクのAZ情報をレスポンスに含めるシンプルなHTTPサーバーです。サービスAからService Connect経由でリクエストし、レスポンスのAZ情報からどのAZのタスクにルーティングされたかを確認します。サービスBを4タスクにしているのは閾値条件(2 × AZ数)を満たすためです。

サービスBのアプリ

from flask import Flask, jsonify
import requests, os

app = Flask(__name__)

@app.route("/")
def az():
    meta_uri = os.environ.get("ECS_CONTAINER_METADATA_URI_V4", "")
    if meta_uri:
        task_meta = requests.get(meta_uri + "/task", timeout=2).json()
        return jsonify({"az": task_meta.get("AvailabilityZone", "unknown")})
    return jsonify({"az": "no-metadata-uri"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Service Connect の設定

サービスBのタスク定義でポートマッピングにnameappProtocolを指定し、サービス作成時にService Connectのサーバー側設定を行います。

{
  "portMappings": [
    {
      "containerPort": 8080,
      "protocol": "tcp",
      "name": "http",
      "appProtocol": "http"
    }
  ]
}

サービス作成時のService Connect設定:

{
  "enabled": true,
  "namespace": "test-sc-zone-aware",
  "services": [
    {
      "portName": "http",
      "discoveryName": "service-b",
      "clientAliases": [
        {
          "port": 8080,
          "dnsName": "service-b"
        }
      ]
    }
  ]
}

サービスA(クライアント側)はクライアントモードのみで設定します:

{
  "enabled": true,
  "namespace": "test-sc-zone-aware"
}

Zone-Awareルーティングのための追加設定は不要です。デフォルトで有効になります。

検証1: Zone-Aware ルーティングの動作確認

サービスAの各AZのタスクにECS Execで接続し、Service Connect経由でservice-bに20回リクエストを送信しました。

# AZ-aのタスクからリクエスト
aws ecs execute-command --cluster test-sc-zone-aware --task <task-id> \
  --container app --interactive \
  --command 'sh -c "for i in $(seq 1 20); do curl -s http://service-b:8080/; echo; done"'

AZ-a(ap-northeast-1a)のタスクから実行:

{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
...(以下すべて同様)

20/20(100%)が同一AZ(ap-northeast-1a)のエンドポイントにルーティングされました。

AZ-c(ap-northeast-1c)のタスクから実行:

{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
...(以下すべて同様)

こちらも20/20(100%)が同一AZ(ap-northeast-1c)にルーティングされました。エンドポイントが均等に配置されている場合、100%同一AZで処理されることが確認できました。

検証2: フォールバック動作の確認

サービスBのAZ-a側のタスクを2つとも手動停止し、AZ-aのクライアントからリクエストした場合の挙動を確認しました。

# AZ-aのservice-bタスクを停止
aws ecs stop-task --cluster test-sc-zone-aware --task <az-a-task-id-1> --reason "test fallback"
aws ecs stop-task --cluster test-sc-zone-aware --task <az-a-task-id-2> --reason "test fallback"

AZ-aのサービスAタスクからリクエスト(停止後20秒待機してから実行):

{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}

10/10(100%)がAZ-cにルーティングされました。AZ-a側のエンドポイントが不在となったことで、リクエストはすべてAZ-cの健全なエンドポイントに送られています。

なお、ECSはdesired-countを維持するために新しいタスクを起動します。同一AZ側に健全なエンドポイントが再び存在しZone-Awareルーティングの条件を満たす状態になると、再び同一AZ優先に戻ります(ドキュメントに記載のフォールバック動作)。

補足: 閾値以下時の挙動

参考として、サービスBが2タスク(各AZに1つ)の状態で同じテストを実施した結果を示します。

{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1c"}
...(14回実行)
AZ 回数 比率
ap-northeast-1a 8 57%
ap-northeast-1c 6 43%

AZ-aとAZ-cにほぼ均等に分散されており、少なくとも同一AZ優先の挙動にはなっていないことが確認できました。ドキュメントの記載どおり、エンドポイント数が閾値(2 × AZ数 = 4)未満の場合はZone-Awareルーティングの条件を満たさず、AZを考慮しない通常の負荷分散にフォールバックします。

注意事項

Fargate環境でのモニタリングについて補足します。

ドキュメントにはEnvoyの統計情報でZone-Awareルーティングの状態を確認する方法が記載されています。確認に使うメトリクスはlb_zone_routing_cross_zonelb_zone_cluster_too_smallです。ただしこの手順はSSM Session ManagerでEC2インスタンスに接続してDocker execする前提です。

Fargate環境ではService Connectエージェントコンテナに直接アクセスできないため、Envoy統計の確認はできませんでした。FargateでクロスAZ通信の傾向を確認する手段としては、VPC Flow Logs(az-idフィールド付き)の利用が選択肢になります。

まとめ

ECS Service ConnectのZone-Awareルーティングにより、マルチAZ構成のサービス間通信で同一AZ内のエンドポイントが優先されるようになりました。追加設定は不要で、条件を満たすService Connectサービスではデフォルトで有効になります。

今回の検証構成では、各AZにエンドポイントを均等配置した状態で100%同一AZにルーティングされることを確認しました。同一AZのエンドポイントが不在になった場合も、別AZの健全なエンドポイントへ自動的にフォールバックされました。

マルチAZでECS Service Connectを利用している環境では、クロスAZ通信を減らし、データ転送コストやレイテンシの削減が期待できます。

参考リンク

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事