Grandream

Grandream

3 min read

AWS ALB経由のAPIリクエストで発生する502エラーの対処法

今回はAWSのApplication Load Balancer(ALB)を使用したシステムでよく遭遇する502エラーについて、その原因と対処法を解説します。

発生する事象

ALBを経由してAPIサーバーへリクエストした際、稀に502エラーが返却されることがあります。具体的には以下のような状態になります:

  • APIを叩いた側は502エラーを受け取っている
  • ALBのメトリクスでも502エラーの記録がある
  • しかし、API側にはエラーログが残っていない 🤔

原因

結論から言うと、以下の条件で発生します:

ALBのアイドルタイムアウト値 < API自体のkeepAlive値

これらの用語について説明します。

アイドルタイムアウト

これは、クライアント-ALB間、ALB-API間のコネクションが確立された後、一定時間データのやり取りがないと接続が切断される仕組みです。ALBのデフォルトでは60秒に設定されています。つまり、60秒間データのやり取りがないと自動的に切断されるということですね。

keepAlive

一方、keepAliveはコネクションを再利用するために一定時間維持する仕組みです。この値で「どのくらいの時間コネクションを維持するか」を指定します。

発生するケース

正常なケース


1. クライアントからALBへリクエスト: クライアント → ALB - APIサーバー
2. ALBからAPIへリクエスト: クライアント - ALB → APIサーバー
3. APIサーバーがレスポンスを返却: クライアント ← ALB ← APIサーバー


エラーが発生するケース


1. クライアントからALBへリクエスト: クライアント → ALB - APIサーバー
2. ALBからAPIへリクエスト: クライアント - ALB → APIサーバー
3. APIがレスポンスを返す前にALB-API間のコネクション切断: クライアント - ALB × APIサーバー
   - API側は正常に処理して返そうとしますが、コネクションが切れているのでALBが受け取れない
4. ALBが502エラーを返却: クライアント ← ALB × APIサーバー


解決方法

解決方法はシンプルです。keepAlive値をALBのアイドルタイムアウト値より大きく設定しましょう。

以下にExpressでの実装例を示します:


const express = require('express');
const http = require('http');

const app = express();

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

const server = http.createServer(app);

// Keep-Aliveタイムアウトの設定
// ALBのデフォルト値(60秒)より余裕を持って65秒に設定
server.keepAliveTimeout = 65000;

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

このように設定することで、ALBのコネクションが切れる前にAPI側のコネクションが切れることがなくなり、502エラーは解消されるはずです。

まとめ

今回は、ALB経由のAPIリクエストで発生する502エラーについて解説しました。エラーの原因は「ALBのアイドルタイムアウト値 < APIのkeepAlive値」という状態にあり、keepAlive値を適切に設定することで解決できます。

Grandream

Grandream

株式会社グランドリーム

AI・システム開発のプロフェッショナルチームです。AIエージェント・業務自動化・Webシステム開発などを手がけています。

Grandream の技術力についてご相談ください

記事の内容についての質問・AI活用・システム開発のご相談をお気軽に。

無料で相談する