🪼
ALB・Webサーバー・アプリケーション間のタイムアウト管理
🐱 はじめに
Webアプリケーションの運用では、ロードバランサーやWebサーバー、アプリケーションの各レイヤーで適切なタイムアウト管理を行うことが重要です。本記事では、AWS ALB、Nginx、PHP(FastCGI)の各レイヤーにおけるチューニングポイントを解説します。
🔄 接続管理とは?
接続管理とは、クライアントとサーバー間のTCPコネクションの維持と切断の仕組みを指します。適切な接続管理ができていないと、以下のような問題が発生する可能性があります。
- 不要な接続の維持 🏗️: タイムアウトが長すぎると、不要なコネクションが残り続け、リソースを圧迫 🛑
- 頻繁な接続の確立 🔄: タイムアウトが短すぎると、同じクライアントが何度も接続を確立し、オーバーヘッドが増大 🌀
- 負荷分散の影響 🎯: 適切なKeep-Alive設定がないと、負荷分散の効果が減少 🚫
各レイヤーにおける適切な接続管理の設定を考慮することで、リソースの最適化とパフォーマンス向上が可能です。
⚙️ 接続管理の設定
1. ALB のアイドルタイムアウト ⏳
- 概要: ALBがクライアントまたはターゲットとのTCP接続を管理し、一定時間データの送受信がないと接続を切断するまでの時間
- 設定:
idle_timeout
(デフォルト値:60秒)
2. Nginx の keepalive_timeout 🌐
- 概要: NginxがクライアントまたはバックエンドサーバーとのTCP接続を維持する時間
- 設定:
keepalive_timeout
(デフォルト値:75秒) - 推奨値:
Nginxのkeepalive_timeout
> ALBのidle_timeout
> PHP のmax_execution_time
解説 📝
- 各設定値について
-
keepalive_timeout
およびidle_timeout
は TCP 接続の維持時間 -
max_execution_time
は PHP スクリプトの実行時間
- 推奨値の理由
-
keepalive_timeout
>idle_timeout
: Nginx が ALB より長く接続を維持することで、ALB が接続を切断する前に Nginx が接続を再利用できる可能性を高める -
idle_timeout
>max_execution_time
: ALB が PHP スクリプトの実行中に接続を切断しないようにする
接続管理のチューニング例 🚀✨
一般的な利用ケースを想定して設定されているデフォルト値を参考にしたチューニング例は以下のようになります。
Nginxの keepalive_timeout: 75 秒
ALBの idle_timeout: 60 秒
PHPの max_execution_time: 30 秒
➡️ デフォルト値の比率:5:4:2
- アプリケーションの特性の把握 📊
- アプリケーションの平均的な処理時間を把握する
- 長時間接続が必要な機能があるかどうかを把握する
- リソースの使用状況(CPU、メモリなど)を監視する 📈
- 最小値の決定 ⚖️
-
max_execution_time
をアプリケーションの平均的な処理時間よりも少し長めに設定する- 例えば、平均処理時間が 10 秒であれば、
max_execution_time
を 15 秒に設定する
- 例えば、平均処理時間が 10 秒であれば、
- 比率を考慮した調整 🔄
-
max_execution_time
を基準に、デフォルト値の比率(5:4:2)を参考にidle_timeout
とkeepalive_timeout
を設定する - 例:
-
max_execution_time
: 60 秒 -
idle_timeout
: 60 秒 × (4/2) = 120 秒 -
keepalive_timeout
: 60 秒 × (5/2) = 150 秒
-
考慮事項 ⚠️
-
リソースの制約 💻
サーバーのリソース(CPU、メモリなど)に制約がある場合は、タイムアウト値を長くしすぎないように注意する -
セキュリティ 🔒
タイムアウト値を長く設定すると、セキュリティリスクが高まる可能性がある
⏳ バックエンドの処理時間管理 とは?
処理時間管理は、バックエンド(NginxやPHP-FPM)がリクエストをどの程度の時間待つかを設定します。適切に設定しないと、以下のような問題が発生します。
- リクエストの切断 🛑: タイムアウトが短すぎると、バックエンドの処理が完了する前にリクエストが切断される
- リソースの浪費 ⚠️: タイムアウトが長すぎると、不要なリクエストが残り続け、リソースを消費する
⚒️ バックエンドの処理時間管理の設定
1. Nginx の タイムアウト 🚀
- 概要: クライアントからのリクエストヘッダーの読み取りにかかる時間を制限する設定
- 設定:
client_header_timeout
(デフォルト値:60秒) - 推奨値: Nginx の
client_header_timeout
> ALB のidle_timeout
- ALBが接続を維持している間にNginxが先にタイムアウトし接続を終了してしまうと、504 エラーが発生する可能性がある
- 参考:
client_body_timeout
(デフォルト値:60秒)- クライアントからのリクエストボディの読み取りにかかる時間を制限する設定
-
client_header_timeout
、client_body_timeout
ともにアプリケーションの応答時間に合わせて適切な値を設定する
2. FastCGI の タイムアウト ⏱️
- 概要: NginxがFastCGIサーバー(PHP-FPMなど)からのレスポンスを読み取るタイムアウト時間
- 設定:
fastcgi_read_timeout
(デフォルト値:60秒) - 推奨値: Nginxの
fastcgi_read_timeout
> PHPのmax_execution_time
- 補足:PHP の
max_execution_time
- 概要: PHPスクリプトがサーバー上で実行できる最大時間(デフォルト値:30 秒)
-
max_execution_time
について、PHPの公式サイトの解説によると...😳この命令は、いい加減に書かれた スクリプトがサーバーの負荷を上げることを防止するのに役立ちます。
🔮 その他 Nginx の推奨設定
1. Keep-Alive リクエスト の最大数 ♻️
- 概要: 1 つの Keep-Alive 接続で処理できるリクエスト数の上限
- 設定:
keepalive_requests
(デフォルト値:1000) - 推奨値:
100
以上
2. Keep-Alive の最大時間
- 概要: アイドル状態の Keep-Alive 接続が閉じられるまでの最大時間
- 設定:
keepalive_time
(デフォルト値:1h) - 推奨値:
10
以上
3. ロギング設定 🐾
- ELB の
X-Forwarded-For
ヘッダーを適切に記録し、元のクライアント IP アドレスを取得できるように設定
log_format combined '$http_x_forwarded_for $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
🩵 おわりに
AWS ALB、Nginx、PHP(FastCGI)の各レイヤーにおけるチューニングポイントをまとめました✍️
もしご指摘やアドバイスがありましたら、コメントいただけますと幸いです📝
えみり〜でした|ωΦ)ฅ
Discussion