本トピックでは、Java、Go、および EAS SDK クライアントで専用ゲートウェイのアイドル接続タイムアウトとリクエストタイムアウトを設定する方法と、一般的なタイムアウト問題のトラブルシューティングについて説明します。
背景情報
タイムアウトが重要な理由
分散システムでは、サービス間の呼び出しチェーンが長くなることがあります。いずれかの時点で遅延や障害が発生すると、リクエストがハングする可能性があります。適切なタイムアウト設定は、以下の点で役立ちます:
リソースの枯渇の防止:応答しないバックエンドサービスを待機している間、クライアントやゲートウェイが接続やスレッドを保持し続けるのを防ぎます。
ユーザーエクスペリエンスの向上:障害を迅速に返し、呼び出し元が必要に応じてリトライやフォールバックを行えるようにします。
システム安定性の維持:リソースを早期に解放し、低速または不健全なサービスが呼び出しチェーン全体に影響を与えるのを防ぎます。
アイドル接続タイムアウトの設定
アイドル接続タイムアウトは、一定期間データ転送がない接続をクローズします。このメカニズムは、コネクションプールを管理し、非アクティブなリソースを解放します。
推奨設定
フルマネージドゲートウェイは、以下の固定アイドル接続タイムアウト値を使用します。これらの値は変更できません。
ゲートウェイ (サーバーとして、クライアント向け):固定値は
600 秒です。クライアントからゲートウェイへの接続がこの期間を超えてアイドル状態になると、ゲートウェイはその接続をクローズします。ゲートウェイ (クライアントとして、バックエンド推論サービス向け):固定値は
30 秒です。ゲートウェイからバックエンドへの接続がこの期間を超えてアイドル状態になると、ゲートウェイはその接続をクローズします。
以下の図は、接続フローを示しています:
クライアントが接続を管理しクローズするように、各リンクを以下のように設定します:
リンク | 推奨設定 | 目的 |
クライアント → ゲートウェイ | クライアントアイドルタイムアウト < ゲートウェイサーバーアイドルタイムアウト | クライアントが、ゲートウェイによってすでにクローズされた接続を再利用するのを防ぐ |
ゲートウェイ → バックエンド推論サービス | ゲートウェイクライアントアイドルタイムアウト < バックエンド推論サービスサーバーアイドルタイムアウト | ゲートウェイが、バックエンド推論サービスによってすでにクローズされた接続を再利用するのを防ぐ |
アップストリームとダウンストリームの値の間に安全マージンを設けてください。関連するタイムアウトを同じ値に設定することは避けてください。
アイドル接続タイムアウトは、リクエスト実行タイムアウトではありません。vLLM と SGLang は HTTP/1.1 Keep-Alive を使用します。このメカニズムでは、エンジンのサーバーアイドルタイムアウトはレスポンスが完了した後にのみ開始され、同じ接続で次のリクエストを待ちます。これを 60 秒に設定しても、長時間実行される推論リクエストやストリーミング推論リクエストが中断されることはありません。
アクセス方法別のデフォルト値
次の表は、各アクセス方法のデフォルトのアイドル接続タイムアウトと、推奨されるクライアントおよびバックエンド推論サービスの設定を示しています。
ゲートウェイのアイドル接続タイムアウト値は変更できません。変更をリクエストするには、チケットを起票してください。
アクセス方法 | ゲートウェイサーバーアイドルタイムアウト | ゲートウェイクライアントアイドルタイムアウト | 推奨クライアントアイドルタイムアウト | 推奨バックエンドサーバーアイドルタイムアウト |
フルマネージドゲートウェイ (MSE ゲートウェイ) | 600 秒 | 30 秒 | 600 秒未満 | 30 秒超 |
ALB 専用ゲートウェイ | 600 秒 | 15 秒 | 600 秒未満 | 15 秒超 |
NLB 負荷分散 | 900 秒 | 900 秒 | 900 秒未満 | 900 秒超 (安全マージンを含む) |
モデルギャラリーのテンプレートのデフォルト値と NLB に関する考慮事項
バックエンド推論サービスのサーバーアイドルタイムアウトは、ゲートウェイのクライアントアイドルタイムアウトより大きい必要があります。
モデルギャラリーのテンプレートを使用して vLLM または SGLang 推論サービスをデプロイすると、テンプレートはデフォルトでエンジンの HTTP Keep-Alive を 60 秒に設定します。
推論フレームワーク | 環境変数 | モデルギャラリーテンプレートのデフォルト値 |
vLLM |
| 60 秒 |
SGLang |
| 60 秒 |
フルマネージドゲートウェイと ALB 専用ゲートウェイの場合、デフォルト設定は次のように機能します:
モデルギャラリーエンジンのサーバーアイドルタイムアウト 60 秒 > ALB ゲートウェイのクライアントアイドルタイムアウト 15 秒
モデルギャラリーエンジンのサーバーアイドルタイムアウト 60 秒 > フルマネージドゲートウェイのクライアントアイドルタイムアウト 30 秒
モデルギャラリーテンプレートのデフォルト値である 60 秒は、ALB 専用ゲートウェイとフルマネージドゲートウェイの両方の要件を満たします。
NLB には特別な注意が必要です:
モデルギャラリーエンジンのサーバーアイドルタイムアウト 60 秒 < NLB のクライアントアイドルタイムアウト 900 秒
この設定では、バックエンド推論サービスが先にアイドル接続をクローズする可能性がありますが、NLB またはアップストリームの接続管理はまだ接続が利用可能であると見なします。このような接続を再利用する後続のリクエストは、EOF、RST、接続リセット、または断続的な 502/503 エラーに遭遇する可能性があります。
モデルギャラリー経由でデプロイされた vLLM または SGLang サービスで NLB を使用する場合、バックエンド推論サービスのサーバーアイドルタイムアウトを 900 秒より大きい値に設定し、安全マージンを設けてください。例:
# vLLM、値の例
VLLM_HTTP_TIMEOUT_KEEP_ALIVE=1000
# SGLang、値の例
SGLANG_TIMEOUT_KEEP_ALIVE=1000EAS サービス環境変数を変更すると、サービスの再構築またはローリングアップデートがトリガーされます。変更はオフピーク時に実行し、事前にレプリカ容量、グレースフルシャットダウン、およびロールバック手順を確認してください。カスタムイメージや古いバージョンのエンジンは、これらの環境変数をサポートしていない場合があります。詳細については、イメージのドキュメントをご確認ください。
クライアント設定の例
クライアントのアイドル接続タイムアウトは、ゲートウェイのサーバーアイドルタイムアウトより短くする必要があります。以下の例は、さまざまなプログラミング言語でクライアントのアイドル接続タイムアウトを管理または設定する方法を示しています。
これらの例はパラメータ参照のみを目的としており、本番システムで直接使用するためのものではありません。実際の値は、トラフィックパターン、負荷条件、およびクライアントのバージョンの特性によって異なります。
Java
Apache HttpClient 4.x のコネクションマネージャーは、定期的に closeIdleConnections() を呼び出すことでアイドル接続をクリーンアップできます。次の例では、クライアントのアイドル接続タイムアウトを 500 秒に設定しています。これは、フルマネージドゲートウェイと ALB 専用ゲートウェイのサーバーアイドルタイムアウトである 600 秒、および NLB のタイムアウトである 900 秒よりも短い値です。
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.client.config.RequestConfig;
import java.util.concurrent.TimeUnit;
public class HttpClientIdleTimeout {
public static void main(String[] args) throws InterruptedException {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// 値の例:ルートごとの最大接続数
cm.setDefaultMaxPerRoute(20);
// 値の例:最大合計接続数
cm.setMaxTotal(100);
RequestConfig requestConfig = RequestConfig.custom()
// 値の例:接続タイムアウト 5 秒
.setConnectTimeout(5000)
// 値の例:読み取りタイムアウト 10 秒
.setSocketTimeout(10000)
.build();
try (CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build()) {
// アイドル接続を定期的にクリーンアップするためのバックグラウンドスレッドを開始
Thread cleanerThread = new Thread(() -> {
try {
while (!Thread.currentThread().isInterrupted()) {
// 値の例:5 秒ごとにチェック
Thread.sleep(5000);
// 500 秒を超えてアイドル状態の接続をクローズ (ゲートウェイのアイドルタイムアウト 600 秒より短い)
cm.closeIdleConnections(500, TimeUnit.SECONDS);
// 期限切れの接続 (サーバーによってクローズされた接続など) をクローズ
cm.closeExpiredConnections();
}
} catch (InterruptedException e) {
// 中断ステータスを復元
Thread.currentThread().interrupt();
}
});
// メインスレッドが終了したときに終了するようにデーモンスレッドとして設定
cleanerThread.setDaemon(true);
cleanerThread.start();
// HTTP リクエストを実行...
// 例:httpClient.execute(new HttpGet("http://your-gateway-url"));
// プログラムが一定期間実行されるのをシミュレート。値の例:1 分間実行
Thread.sleep(60000);
// クリーナースレッドを停止 (本番環境では、アプリケーションのシャットダウン中にグレースフルシャットダウンを実行)
cleanerThread.interrupt();
} catch (Exception e) {
e.printStackTrace();
}
}
}Go
Go の net/http ライブラリでは、Transport.IdleConnTimeout を使用してクライアントのコネクションプールのアイドルタイムアウトを設定できます。
package main
import (
"net/http"
"time"
)
func main() {
// カスタム Transport を作成
tr := &http.Transport{
MaxIdleConns: 100, // アイドル接続の最大数
IdleConnTimeout: 500 * time.Second, // アイドル接続タイムアウト、例:500 秒 (600 秒未満)
DisableKeepAlives: false, // Keep-Alive を有効化
}
}EAS SDK (Java)
EAS SDK は、アイドル接続のクリーンアップ間隔とクライアントのアイドル接続タイムアウトの設定をサポートしています。
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class EasSdkTimeoutJava {
public static void main(String[] args) {
// 1. グローバルクライアント設定
HttpConfig httpConfig = new HttpConfig();
// アイドル接続のクリーンアップを有効化 (ミリ秒単位)。クライアントの要件に基づいて設定します。
httpConfig.setConnectionCleanupInterval(5000);
// アイドル接続タイムアウトを 500 秒に設定します。これはフルマネージドゲートウェイのアイドルタイムアウト 600 秒より短い値です。
httpConfig.setIdleConnectionTimeout(500000);
...
}
}上記のコードは、クライアントからゲートウェイへの接続のみを設定します。ゲートウェイからモデルサービスへのクライアントアイドルタイムアウトや、vLLM/SGLang のサーバーアイドルタイムアウトは変更しません。
リクエストタイムアウトの設定
リクエストタイムアウトは、TCP 接続の確立とリクエストの送信から、完全なレスポンスの受信までに許容される最大時間です。これは、クライアントで最も一般的に設定されるタイムアウトです。
推奨設定
ビジネス要件に基づいてリクエストタイムアウトを調整してください。本番環境では、フォールトトレランス、応答性、モデルの処理時間、ネットワークのジッターのバランスを取る必要があります。
サーバーがまだ処理中にクライアントがタイムアウトするのを防ぐために、クライアントのリクエストタイムアウトをゲートウェイのリクエストタイムアウトよりわずかに高く設定します。
一般的な計算式:
クライアントタイムアウト = サーバーリクエストタイムアウト + 1~5 秒。フェイルファストのシナリオでは、クライアントのタイムアウトを短く設定し、べき等性とリトライ戦略に依存して障害を処理します。
10 分を超える長時間実行されるシナリオの場合は、代わりに以下のいずれかのアプローチを使用してください:
ストリーミング (AI コンテンツ生成や大容量ファイルのダウンロードなど)。
WebSocket (永続的な双方向通信のため)。
非同期推論またはタスクポーリング。
フルマネージドゲートウェイのデフォルトのリクエストタイムアウトは 10 分 (600 秒) です。以下の図は、リクエストタイムアウトのフローを示しています:
アクセス方法別のリクエストタイムアウト
アクセス方法 | リクエストタイムアウトの説明 |
フルマネージドゲートウェイ (MSE ゲートウェイ) | デフォルトのリクエストタイムアウト:600 秒。サービス設定ファイルの |
ALB 専用ゲートウェイ |
|
NLB 負荷分散 | NLB はレイヤー 4 のロードバランサーであり、HTTP リクエストを解析しないため、HTTP リクエストレベルのタイムアウトは提供しません。リクエストは、クライアント、アップストリームプロキシ、バックエンドサービスのタイムアウト、および NLB の TCP アイドルタイムアウトの影響を受けます。 |
リクエストタイムアウトと HTTP Keep-Alive アイドルタイムアウトは異なるパラメータです。エンジンのサーバーアイドルタイムアウトが 60 秒であっても、1 回の推論が 60 秒に制限されるわけではありません。ただし、長期間ネットワークデータがない非ストリーミングリクエストの場合、NLB の TCP アイドルタイムアウトが適用される可能性があります。最初のトークンまでの時間 (TTFT) の最大値と実際の応答パターンに照らしてタイムアウトを検証してください。
クライアント設定の例
以下の例は、さまざまなプログラミング言語でクライアントのリクエストタイムアウトを設定する方法を示しています。
これらの例はパラメータ参照のみを目的としており、本番システムで直接使用するためのものではありません。実際の値は、トラフィックパターン、負荷条件、およびクライアントのバージョンの特性によって異なります。
Java
次の例は、クライアントのリクエストタイムアウトを設定する方法を示しています。実際の値は、ゲートウェイの種類とモデルの処理時間に基づいて調整してください。
import org.apache.http.client.config.RequestConfig;
public class ApacheHttpClientTimeout {
public static void main(String[] args) {
// クライアントのリクエストタイムアウトを、ゲートウェイのリクエストタイムアウトよりわずかに高く設定します。
// ゲートウェイのデフォルトが 600 秒の場合、ここでは 610 秒を使用します。
RequestConfig requestConfig = RequestConfig.custom()
// 値の例:接続タイムアウト (ミリ秒単位)
.setConnectTimeout(5000)
// データ転送タイムアウト (読み取りタイムアウト) (ミリ秒単位、610 秒)
.setSocketTimeout(610000)
.build();
}
}Go
Go の net/http ライブラリには、リクエストタイムアウトを設定する複数の方法があります。最も一般的なアプローチは、http.Client の Timeout を設定するか、リクエストごとに context.WithTimeout を使用することです。
package main
import (
"context"
"fmt"
"io"
"net/http"
"time"
)
func main() {
// 推奨:クライアントのリクエストタイムアウトをゲートウェイのリクエストタイムアウト (デフォルト 600 秒) と同等か、わずかに大きく設定します。ここでは 610 秒を使用します。
client := &http.Client{
Timeout: 610 * time.Second, // リクエスト全体に対するタイムアウト
}
req, err := http.NewRequest("GET", "http://your-gateway-url", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
// 個々のリクエストに対して、より短いタイムアウトを設定することもできます
ctx, cancel := context.WithTimeout(req.Context(), 610*time.Second) // 610 秒
defer cancel()
req = req.WithContext(ctx)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
// タイムアウトエラーかどうかを確認
if t, ok := err.(interface{ Timeout() bool }); ok && t.Timeout() {
fmt.Println("Request timed out!")
}
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
fmt.Printf("Response Status: %s\n", resp.Status)
fmt.Printf("Response Body: %s\n", body)
}EAS SDK (Java)
Alibaba Cloud EAS SDK は、グローバルクライアントレベルとリクエストごとのレベルの両方で、接続タイムアウトと読み取りタイムアウトの設定をサポートしています。
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class EasSdkTimeoutJava {
public static void main(String[] args) {
// 1. グローバルクライアント設定
HttpConfig httpConfig = new HttpConfig();
// 接続タイムアウト (ミリ秒単位)
httpConfig.setConnectTimeout(5000);
// 読み取りタイムアウト (ミリ秒単位)。クライアントのリクエストタイムアウトを、ゲートウェイのリクエストタイムアウトよりわずかに高く設定します。
// ゲートウェイのデフォルトが 600 秒の場合、ここでは 610 秒 (610000 ミリ秒) を使用します。
httpConfig.setReadTimeout(610000);
}
}一般的な問題
アイドル接続タイムアウトの誤設定
シナリオ 1:クライアントのアイドルタイムアウトがゲートウェイのサーバーアイドルタイムアウトを超えている
症状:クライアントのコネクションプールは接続が有効であると見なしますが、ゲートウェイはすでにその接続をクローズしています。その接続を再利用する後続のリクエストは失敗します。
一般的なエラーは次のとおりです:
Connection reset by peerBroken pipejava.net.SocketException: Connection resetrequests.exceptions.ConnectionErrorread: connection reset by peer
接続がクローズされたタイミングとゲートウェイの処理ロジックによっては、クライアントは HTTP 503 を受信することもあります。
トラブルシューティング:ゲートウェイの種類を特定し、クライアントのアイドルタイムアウトを対応するゲートウェイのサーバーアイドルタイムアウトより短く設定します。デフォルトでは、フルマネージドゲートウェイと ALB 専用ゲートウェイは 600 秒、NLB は 900 秒を使用します。
シナリオ 2:ゲートウェイのクライアントアイドルタイムアウトがバックエンド推論サービスのサーバーアイドルタイムアウトを超えている
症状:ゲートウェイはバックエンド接続が再利用可能であると見なしますが、バックエンド推論サービスはアイドルタイムアウトのためにすでにその接続をクローズしています。ゲートウェイがその接続を再利用しようとすると、接続が切断されていることが判明します。
クライアントは HTTP 502、503、または接続リセットを受信する可能性があります。ゲートウェイが接続のクローズを時間内に検出すれば新しい接続を確立できるため、この問題は通常、断続的に発生します。
トラブルシューティング:
ゲートウェイの種類とそのクライアントアイドルタイムアウトを特定します:フルマネージドゲートウェイは 30 秒、ALB 専用ゲートウェイは 15 秒、NLB は 900 秒です。
バックエンド推論エンジンのサーバーアイドルタイムアウトを確認してください。
バックエンド推論サービスのサーバーアイドルタイムアウトが、ゲートウェイのクライアントアイドルタイムアウトより大きいことを確認してください。
NLB の場合、モデルギャラリーテンプレートのデフォルト値である 60 秒を確認し、900 秒を超える値に増やします。
必要に応じて、パケットキャプチャを使用して、前のレスポンスが完了した後の FIN パケットと RST パケットの順序を特定します。これにより、どのレイヤーが接続の切断を開始したかを特定できます。
リクエストタイムアウトの誤設定
シナリオ 1:クライアントのリクエストタイムアウトが短すぎる
ゲートウェイまたはバックエンド推論サービスが処理を終える前にクライアントが切断し、誤ったタイムアウトが発生する可能性があります。一般的なエラーは次のとおりです:
java.net.http.HttpTimeoutExceptionjava.net.SocketTimeoutException: Read timed outrequests.exceptions.ReadTimeoutcontext deadline exceeded
クライアントのリクエストタイムアウトは、フェイルファスト戦略に基づいて調整できます。すべてのシナリオでクライアントのタイムアウトがサーバーのリクエストタイムアウトを超える必要があるわけではありません。
シナリオ 2:ゲートウェイのリクエストタイムアウトが実際のモデル処理時間より短い
バックエンド推論サービスが終了する前に、ゲートウェイは待機を停止します。クライアントは通常 HTTP 504 を受信しますが、接続が切断された場所によっては 502 または 500 を受け取ることもあります。バックエンド推論サービスは処理を続行するか、ゲートウェイが接続をクローズした後にリクエストのキャンセルを検出する場合があります。
トラブルシューティングのために、以下の情報を収集してください:
クライアントのエラーの種類、リクエスト期間、リトライ履歴。
ゲートウェイのアクセスログから得られるステータスコード、リクエスト期間、バックエンドの応答時間。
バックエンド推論サービスのログから得られるリクエストステータス、モデル処理時間、接続中断の詳細。
非ストリーミングリクエストの場合:最初のトークンまでの時間 (TTFT)、合計応答時間、およびリンクの TCP アイドルタイムアウト。
変更と検証のガイドライン
アクセス方法を確認してください:フルマネージドゲートウェイ、ALB 専用ゲートウェイ、または NLB。
クライアントアイドルタイムアウト、ゲートウェイサーバーアイドルタイムアウト、ゲートウェイクライアントアイドルタイムアウト、バックエンド推論サービスサーバーアイドルタイムアウト、およびリクエストタイムアウトを記録してください。
アイドル接続タイムアウト、リクエストタイムアウト、読み取りタイムアウト、および TCP Keep-Alive プローブ間隔を区別してください。
EAS 推論エンジンの環境変数を変更すると、サービスの再構築がトリガーされます。変更はオフピーク時に実行してください。
変更後、新しいインスタンスで環境変数と実際の HTTP サーバー設定が有効になっていることを確認してください。
ターゲットのアイドルタイムアウトを下回る間隔と上回る間隔の両方で接続をテストし、接続がどのようにクローズされ、再確立されるかを観察してください。
クライアントログ、ゲートウェイログ、パケットキャプチャを使用して、どのレイヤーが FIN、RST、502/503/504 エラーを生成しているかを特定します。
接続数、ファイル記述子、5xx 比率、成功率、およびリクエストレイテンシーを監視します。ロールバック計画を準備します。