Movatterモバイル変換


[0]ホーム

URL:


developersIOproduced by Classmethod

ALBの新機能 Target Optimizer による同時接続数の制御を試してみた

ALBの新機能 Target Optimizer による同時接続数の制御を試してみた

2025年11月にリリースされたALBの新機能、Target Optimizerを検証。エージェント連携によりターゲットの同時接続数を厳密に制御し、過負荷時に即座に503を返す挙動を確認しました。生成AI・LLMアプリのGPU枯渇対策(バルクヘッド)に活用できます。
2025.11.22

2025年11月20日、Application Load Balancer (ALB) の新機能、ターゲットオプティマイザー (Target Optimizer) がリリースされました。

https://aws.amazon.com/jp/blogs/networking-and-content-delivery/drive-application-performance-with-application-load-balancer-target-optimizer/

これまではWAFやWebサーバ側で行っていた同時接続数の制御が、ALBとターゲット間の連携によってより効果的に行えるようになります。 今回、ALB配下のターゲットの同時接続数を一定以下に制御し、過剰な接続による性能劣化を回避できるか、試す機会がありましたので、紹介します。

環境構成

今回は ECS のサイドカー構成を模倣するため、EC2 上で Docker を利用し、--network host モードでエージェントとアプリケーションを同居させました。

  • OS: Amazon Linux 2023 (al2023-ami-2023.9.20251117.1-kernel-6.1-x86_64)
  • App: Node.js (クエリパラメータで遅延を制御)
  • Agent: AWS Target Optimizer Agent

EC2 (Docker & アプリ)

1秒の遅延を意図的に発生させる Node.js アプリケーションと、ALB からのリクエストを中継・制御する Target Optimizer agent を起動しました。

#!/bin/bash# 1. システムパッケージを最新化yum update-y# 2. Dockerをインストールyuminstall-ydocker# 3. Dockerサービスを起動・有効化systemctl startdockersystemctlenabledocker# 4. Target Optimizer agentイメージをダウンロードdocker pull public.ecr.aws/aws-elb/target-optimizer/target-control-agent:latest# 5. Node.jsアプリケーションのディレクトリを作成mkdir-p /app# 6. 遅延可能なNode.jsアプリケーションを作成(クエリパラメータ ?delay=<ms> で遅延時間を指定)cat> /app/app.js<<'EOF'require('http').createServer(async (req, res) => {  const delay = parseInt(new URL(req.url, 'http://localhost').searchParams.get('delay')) || 0;  if (delay > 0) await new Promise(r => setTimeout(r, delay));  res.writeHead(200, {'Content-Type': 'text/plain'});  res.end(`OK (${delay}ms delay)\n`);}).listen(8080, () => console.log('Server running on port 8080'));EOF# 7. Dockerfileを作成cat> /app/Dockerfile<<'EOF'FROM node:alpineCOPY app.js .CMD ["node", "app.js"]EOF# 8. Dockerイメージをビルドcd /app&&docker build-t delay-app.# 9. Node.jsアプリケーションコンテナを起動docker run-d\--name delay-app\--restart unless-stopped\--networkhost\  delay-app# 10. Target Optimizer agentコンテナを起動docker run-d\--name target-optimizer-agent\--restart unless-stopped\--networkhost\-eTARGET_CONTROL_DATA_ADDRESS=0.0.0.0:80\-eTARGET_CONTROL_CONTROL_ADDRESS=0.0.0.0:3000\-eTARGET_CONTROL_DESTINATION_ADDRESS=127.0.0.1:8080\-eTARGET_CONTROL_MAX_CONCURRENCY=1\  public.ecr.aws/aws-elb/target-optimizer/target-control-agent:latest

ALB ターゲットグループ作成

検証用のALBを作成しました。

ターゲットグループ作成時、--target-control-port 設定を実施しました。
これにより、ALB は指定したポート(今回は3000)を通じてエージェントと通信し、混雑状況を把握します。

Target Optimizer有効のTarget Groupを作成(CLI)

aws elbv2 create-target-group\--name optimized-tg\--protocol HTTP\--port80\  --vpc-id<VPC-ID>\  --target-control-port3000\--region ap-northeast-1# --target-control-port でエージェントとの通信ポートを指定
  • マネージドルール(GUI)設定

ターゲットコントロールポート設定

今回 EC2のエージェントに合わせ、ターゲットコントロールポートは「3000」。 Target Optimizer agentコンテナのポート「80」を通信先としました。

動作検証

リクエスト毎に意図的に「1秒」の遅延を発生させ、同時接続数制限(今回は1)を超えた場合にどう挙動するかを確認しました。

テストスクリプト
#!/bin/bashDELAY=${1:-0}ALB_DNS=$(aws elbv2 describe-load-balancers--region ap-northeast-1--query'LoadBalancers[0].DNSName'--output text)URL="http://$ALB_DNS/?delay=$DELAY"run_requests(){localPARALLEL=$1localRESULT=$(seq1 $PARALLEL|xargs-P $PARALLEL-I{}curl-s--http1.1-o /dev/null-w"%{http_code}\n""$URL"2>/dev/null)localS=$(echo"$RESULT"|grep-c"200"||true)localF=$(echo"$RESULT"|grep-c"503"||true)echo"$S$F"sleep1}echo"=== テスト設定 ==="echo"遅延時間:${DELAY}ms"echo"URL:$URL"echo""echo"=== ウォームアップ中(2並列、10秒間)==="START_TIME=$(date +%s)WARMUP_SUCCESS=0WARMUP_FAILED=0while[$(($(date+%s)- START_TIME))-lt10];doread S F<<<$(run_requests2)WARMUP_SUCCESS=$((WARMUP_SUCCESS+ S))WARMUP_FAILED=$((WARMUP_FAILED+ F))doneecho"ウォームアップ完了: 成功=$WARMUP_SUCCESS, 失敗=$WARMUP_FAILED"echo""sleep2echo"=== Target Optimizer 並列負荷テスト (各30秒間) ==="echo"並列数 | 成功(200) | 失敗(503) | 成功率"echo"-------|-----------|-----------|-------"forPARALLELin124816;doSTART_TIME=$(date +%s)SUCCESS=0FAILED=0while[$(($(date+%s)- START_TIME))-lt30];doread S F<<<$(run_requests $PARALLEL)SUCCESS=$((SUCCESS+ S))FAILED=$((FAILED+ F))doneTOTAL=$((SUCCESS+ FAILED))if[$TOTAL-gt0];thenRATE=$(awk"BEGIN {printf\"%.1f%%\", ($SUCCESS*100.0/$TOTAL)}")elseRATE="0.0%"fiprintf"%6d | %9d | %9d | %s\n"$PARALLEL$SUCCESS$FAILED"$RATE"doneecho""echo"=== テスト完了 ==="

検証結果

並列数を 1 から 16 まで増やして負荷をかけました。 EC2は2台構成、各エージェントの設定は MAX_CONCURRENCY=1 です。

並列数成功(200)失敗(503)成功率
115193.8%
221970.0%
4303050.0%
8309025.0%
163021012.5%

並列数を増やしても、成功数は「30」で頭打ちになり、超過分は期待通り 503 Service Unavailable となりました。

※ 成功数が30件である理由: アプリの処理時間(1秒) + スクリプトの待機時間(1秒) = 1サイクル約2秒。 30秒間のテストでおよそ15サイクル実行され、2台のEC2がそれぞれ1リクエストずつ処理したため(15回 × 2台 = 30回)と考えられます。

アクセスログの確認

ALBのアクセスログからも、Target Optimizerの動作が確認できました。

  • 成功ログ(200)

処理時間(target_processing_time)が 1.004s となっており、アプリでの1秒遅延を経て正常に返されていました。

項目
プロトコルhttp
時刻2025-11-21T16:10:02.724784Z
ALBapp/alb-XXXXX/a7c2180283d10881
クライアント203.xx.xx.xx:53426
ターゲット172.31.24.14:80
処理時間request=0.000s / target=1.004s / response=0.000s
ELBステータス200
ターゲットステータス200
受信バイト144
送信バイト163
リクエストGET /?delay=1000 HTTP/1.1
User-Agentcurl/8.11.1
http 2025-11-21T16:10:02.724784Z app/alb-XXXXX/a7c2180283d10881 203.xx.xx.xx:53426 172.31.24.14:80 0.0001.004 0.000 200 200 144 163 "GET http://my-alb-XXXXX.ap-northeast-1.elb.amazonaws.com:80/?delay=1000 HTTP/1.1" "curl/8.11.1" - - arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/optimized-tg/41e7338699cf44e9 "Root=1-69208ed9-4b1b24d81a741acd3b4a42dd" "-" "-" 0 2025-11-21T16:10:01.720000Z "forward" "-" "-" "172.31.24.14:80" "200" "-" "-" TID_7290691baf7245469508aa6a42bd733c "-" "-" "-"
  • 失敗ログ(503)

ターゲットに到達する前(target ipが -)に、ALBまたはエージェントの判断により 503 が返却されています。
Target Optimizerにより、バックエンドのアプリに負荷をかけない保護が実現できていることが確認できました。

項目
プロトコルhttp
時刻2025-11-21T16:10:01.738713Z
ALBapp/alb-XXXXX/a7c2180283d10881
クライアント203.xx.xx.xx:53464
ターゲット- (到達せず)
処理時間request=-1s / target=-1s / response=-1s
ELBステータス503
ターゲットステータス-
受信バイト144
送信バイト162
リクエストGET /?delay=1000 HTTP/1.1
User-Agentcurl/8.11.1

※ALBアクセスログでは、リクエストがターゲットに到達しなかった場合、処理時間フィールドに -1 が記録されます。

http 2025-11-21T16:10:01.738713Z app/alb-XXXXX/a7c2180283d10881 203.xx.xx.xx:53464 - -1 -1 -1 503 - 144 162 "GET http://my-alb-XXXXX.ap-northeast-1.elb.amazonaws.com:80/?delay=1000 HTTP/1.1" "curl/8.11.1" - - arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/optimized-tg/41e7338699cf44e9 "Root=1-69208ed9-4a2f731a0e5fabfe6f9d184f" "-" "-" 0 2025-11-21T16:10:01.736000Z "forward" "-" "-" "-" "503" "-" "-" TID_3e941d6f5423694e9f3f8e512cc30b7c "-" "-" "-"

まとめ

今回の検証により、Target Optimizer を利用することで、アプリケーションの限界を超えたリクエストを ターゲットに到達させる前に 遮断できることが確認できました。

ALBレベル(エージェント連携)で制御されるため、アプリケーションプロセスを守る「流量制限(バルクヘッド)」の手段として非常に有効です。

今回はEC2上のDockerで検証しましたが、特に Amazon ECS のサイドカーパターンで導入する場合、タスクごとの厳密な同時実行数の制御に利用できます。

特に、1リクエストの処理時間が長く、GPUリソースなどに物理的な並列限界がある「生成AI・LLMアプリケーション」などで、システム全体の安定稼働を守る手段としてご活用ください。

この記事をシェアする

FacebookHatena blogX

EVENTS

セミナー一覧会社説明会一覧勉強会一覧

関連記事

もうSQL文に悩まない!Claude Code + Athena で自然言語によるログ解析をやってみた
M.Shimizu
2025.12.11
ネイティブアプリからALBでJWT検証をしたい
つやたく
2025.11.25
ALB/NLBが ポスト量子鍵共有 (Post-Quantum Key Exchange)をサポートしました。
suzuki.ryo
2025.11.23
ALBがサポートしたヘルスチェックログをCloudFormationで設定して確認してみた
suzuki.ryo
2025.11.23

[8]ページ先頭

©2009-2025 Movatter.jp