专属网关涉及两种核心超时:空闲连接超时和请求超时。设置不当可能导致连接重置、请求堆积,甚至引发服务雪崩。本文说明两种超时的配置建议,提供 Java、Go 及 EAS SDK 的客户端代码示例,并分析常见超时问题的排查方法。
背景信息
为什么需要设置超时时间
在分布式系统中,服务之间的调用链路可能较长,任意环节的延迟或故障都可能导致请求卡顿。合理设置超时时间可以:
防止资源耗尽:避免客户端或网关长时间等待无响应的后端服务,持续占用连接和线程。
提升用户体验:让调用方及时获得失败结果,并根据需要执行重试或降级。
保障系统稳定性:及时释放资源,避免慢请求或故障服务影响整个调用链路。
设置空闲连接超时时间
空闲连接超时(Idle Connection Timeout)指连接在一段时间内无数据传输后被关闭。该机制用于管理连接池、释放不活跃资源。
配置建议
以全托管网关为例,专属网关配置了以下固定的空闲连接超时时间,不支持修改:
网关作为服务端(面向客户端):固定为
600 秒。客户端与网关的连接若空闲超过此时间,将被网关关闭。网关作为客户端(面向模型服务):固定为
30 秒。网关与后端模型服务的连接若空闲超过此时间,将被网关关闭。
链路如下图所示:
为确保由客户端主动管理和关闭连接,完整链路配置建议如下:
链路 | 配置建议 | 目的 |
客户端 → 网关 | 客户端 Idle Timeout < 网关 Server Idle Timeout | 避免客户端复用已被网关关闭的连接 |
网关 → 后端推理服务 | 网关 Client Idle Timeout < 后端推理服务 Server Idle Timeout | 避免网关复用已被模型服务关闭的连接 |
建议上下游之间预留一定安全余量,不要将两个值设置得完全相同。
空闲连接超时不是请求执行超时。以 vLLM、SGLang 使用的 HTTP/1.1 Keep-Alive 为例,引擎的 Server Idle Timeout 通常在一次响应完整结束后才开始计时,用于等待同一连接上的下一次请求,不会因为设置为 60 秒就直接中断一个正在执行或正在流式返回的长耗时推理请求。
各接入方式默认值
下表列出各接入方式的网关默认空闲连接超时时间,以及基于默认值的客户端和后端推理服务配置建议。
网关空闲连接超时时间不支持用户修改,如需调整,请提工单获取帮助。
接入方式 | 网关 Server Idle Timeout | 网关 Client Idle Timeout | 客户端 Idle Timeout 建议 | 后端推理服务 Server Idle Timeout 建议 |
全托管网关(MSE 网关) | 600 秒 | 30 秒 | 小于 600 秒 | 大于 30 秒 |
ALB 专属网关 | 600 秒 | 15 秒 | 小于 600 秒 | 大于 15 秒 |
NLB 负载均衡 | 900 秒 | 900 秒 | 小于 900 秒 | 大于 900 秒,并预留安全余量 |
Model Gallery模板默认值(NLB风险)
后端推理服务的 Server Idle Timeout 需大于网关 Client Idle Timeout。
使用 Model Gallery 模板部署 vLLM 或 SGLang 推理服务时,模板默认将引擎 HTTP Keep-Alive 配置为 60 秒。
推理框架 | 环境变量 | Model Gallery 模板默认值 |
vLLM |
| 60 秒 |
SGLang |
| 60 秒 |
对于全托管网关和 ALB 专属网关,默认配置关系如下:
Model Gallery 引擎 Server Idle Timeout 60 秒 > ALB 网关 Client Idle Timeout 15 秒
Model Gallery 引擎 Server Idle Timeout 60 秒 > 全托管网关 Client Idle Timeout 30 秒
因此,在使用默认 ALB 专属网关或全托管网关时,Model Gallery 模板配置的 60 秒通常能够满足要求。
NLB 场景需要特别注意:
Model Gallery 引擎 Server Idle Timeout 60 秒 < NLB Client Idle Timeout 900 秒
在该配置下,后端推理服务可能先关闭空闲连接,而 NLB 或上游连接管理逻辑仍可能暂时认为连接可用。后续请求如果恰好复用该连接,可能出现 EOF、RST、连接重置或偶发 502/503。
使用 NLB 接入 Model Gallery 部署的 vLLM 或 SGLang 服务时,应将后端推理服务 Server Idle Timeout 设置为大于 900 秒,并预留安全余量。例如:
# vLLM,示例值
VLLM_HTTP_TIMEOUT_KEEP_ALIVE=1000
# SGLang,示例值
SGLANG_TIMEOUT_KEEP_ALIVE=1000修改 EAS 服务环境变量会触发服务重建或滚动更新。建议在业务低峰期操作,并提前确认副本容量、优雅终止和回滚方案。自定义镜像或旧版本引擎是否支持上述环境变量,应以实际镜像版本和启动方式为准。
客户端配置示例
客户端 Idle Timeout 需小于网关 Server Idle Timeout。以下是针对不同编程语言管理或设置客户端空闲连接超时时间的示例。
示例仅供参数设置参考,不能直接用于业务系统。实际设置需考虑业务流量、负载情况和客户端版本特性。
Java
Apache HttpClient 4.x 的连接管理器可以通过周期性调用 closeIdleConnections() 清理空闲连接。以下示例将客户端空闲连接超时设置为 500 秒,小于全托管网关和 ALB 专属网关的 Server Idle Timeout 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);
...
}
}上述代码只配置业务客户端到网关这一段连接,不会修改网关到模型服务的 Client Idle Timeout,也不会修改 vLLM 或 SGLang 的 Server Idle Timeout。
设置请求超时时间
请求超时(Response Timeout)指从TCP连接建立、发送请求到接收完整响应的最大允许时间,是客户端最常用的超时设置。
配置建议
请求超时时间应根据实际业务需求调整。生产环境中需要综合考虑容错性、即时性、模型处理时间和网络抖动。
为了避免客户端已经超时、服务端仍在处理请求,客户端请求超时可以略大于网关请求超时。
通常建议
客户端超时 = 服务端请求超时 + 1~5 秒缓冲时间。如果业务需要快速失败,也可以根据幂等性和重试策略设置更短的客户端超时。
对于超过 10 分钟的长耗时场景,推荐采用:
流式传输(Streaming),例如 AI 内容生成和大文件下载。
WebSocket,用于需要持续双向通信的场景。
异步推理或任务轮询方式。
以全托管网关为例,默认请求超时为 10 分钟(600 秒)。链路如下图所示:
各接入方式的请求超时时间
接入方式 | 请求超时说明 |
全托管网关(MSE 网关) | 默认请求超时为 600 秒;支持在服务配置文件中通过 |
ALB 专属网关 | 不支持通过 |
NLB 负载均衡 | NLB 是四层负载均衡,不解析 HTTP 请求,因此不提供 HTTP 请求级超时;请求仍受客户端、上层代理和后端服务超时约束,同时受 NLB TCP Idle Timeout 影响。 |
请求超时与 HTTP Keep-Alive 空闲超时不是同一个参数。引擎 Server Idle Timeout 为 60 秒,不表示单次推理只能执行 60 秒。但是,对于长时间没有任何网络数据的非流式请求,NLB 的 TCP Idle Timeout 仍可能生效,应结合最大 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)
阿里云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(5);
// 读取超时 建议客户端请求超时略大于等于网关请求超时时间(如果是默认的600秒),这里可以是610秒
httpConfig.setReadTimeout(610);
}
}常见问题
空闲连接超时设置不当
场景一:客户端空闲连接超时大于网关 Server Idle Timeout
问题描述:客户端连接池认为连接仍然有效,但网关已经关闭连接。客户端再次复用连接时,请求可能失败。
常见错误包括:
Connection reset by peerBroken pipejava.net.SocketException: Connection resetrequests.exceptions.ConnectionErrorread: connection reset by peer
客户端也可能收到 HTTP 503,具体取决于连接关闭时机和网关处理逻辑。
排查和处理:确认实际网关类型,将客户端 Idle Timeout 设置为小于对应的网关 Server Idle Timeout。默认情况下,全托管网关和 ALB 专属网关为 600 秒,NLB 为 900 秒。
场景二:网关 Client Idle Timeout 大于模型服务 Server Idle Timeout
问题描述:网关仍认为后端连接可以复用,但模型服务已经因空闲超时主动关闭连接。网关再次使用该连接时,可能发现连接已经断开。
客户端可能收到 HTTP 502、503 或连接重置。该问题通常表现为偶发,因为网关如果及时感知连接关闭,可以直接建立新连接。
排查和处理:
确认网关类型及其 Client Idle Timeout:全托管网关 30 秒、ALB 专属网关 15 秒、NLB 900 秒。
确认后端推理引擎的 Server Idle Timeout。
保证后端推理服务 Server Idle Timeout 大于网关 Client Idle Timeout。
NLB 场景重点检查 Model Gallery 模板默认的 60 秒,并调整为大于 900 秒。
必要时通过抓包确认前一响应结束后,哪一层首先发送 FIN 或 RST。
请求超时设置不当
场景一:客户端请求超时设置过短
客户端可能在网关或模型服务完成处理前主动断开连接,产生虚假超时。常见错误包括:
java.net.http.HttpTimeoutExceptionjava.net.SocketTimeoutException: Read timed outrequests.exceptions.ReadTimeoutcontext deadline exceeded
客户端请求超时可根据业务的快速失败策略灵活设置,并非所有场景都必须大于服务端请求超时。
场景二:网关请求超时小于模型服务实际处理时间
网关在模型服务完成处理前停止等待,客户端通常收到 HTTP 504,也可能因具体链路行为收到 502 或 500。模型服务可能仍在继续处理请求,或者在网关关闭连接后感知到请求取消。
建议结合以下信息排查:
客户端异常类型、请求耗时和重试记录。
网关访问日志中的状态码、请求耗时和后端响应耗时。
模型服务日志中的请求状态、模型处理耗时和连接中断信息。
非流式请求的 TTFT、总响应时间以及链路 TCP Idle Timeout。
变更与验证建议
确认接入方式是全托管网关、ALB 专属网关还是 NLB。
分别记录业务客户端 Idle Timeout、网关 Server Idle Timeout、网关 Client Idle Timeout、后端推理服务 Server Idle Timeout 和请求超时。
区分连接空闲超时、请求超时、读取超时和 TCP Keep-Alive 探测周期。
修改 EAS 推理引擎环境变量会触发服务重建,建议在业务低峰期执行。
变更后确认新实例中的环境变量和实际 HTTP Server 配置已经生效。
分别在小于和大于目标 Idle Timeout 的时间点复用连接,观察连接关闭和重新建连行为。
结合客户端日志、网关日志和抓包确定 FIN、RST 以及 502/503/504 的实际产生层。
持续观察连接数、文件描述符、5xx 比例、成功率和请求延迟,并准备回滚。