You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Socket超时发生时底层TCP连接会发生什么?HTTP1与HTTP2表现有何差异?

前置场景

假设我们有一个类似Spring RestTemplate 的Java Web客户端,可以对其配置读取超时:

RestTemplateBuilder()
        .setReadTimeout(Duration.ofMillis(1000))
        .build()

发起HTTP调用后如果服务器响应过慢,会抛出异常:java.net.SocketTimeoutException


1. 超时发生时底层TCP连接的变化

Linux下poll系统调用触发超时的时候,内核不会主动关闭TCP连接,只会返回超时的事件通知,将控制权交回用户态进程,后续的连接处理逻辑完全由上层应用实现决定:

  • 如果你使用的是默认JDK HttpURLConnection 作为RestTemplate的底层客户端:触发SocketTimeoutException后,JDK会主动调用close()关闭套接字,后续服务端发送的响应数据包到达时,内核会直接回复RST报文丢弃,不会向上层转发。
  • 如果你使用的是Apache HttpClient、OkHttp这类支持连接池的客户端实现:读取超时发生后,客户端会判定该连接存在未确定的残留数据,为了避免后续复用连接时出现请求/响应串位的问题,会将该连接从连接池中移除并主动关闭,不会再复用该连接。

如果上层应用没有主动关闭连接,后续服务端的响应数据会正常存入内核的套接字接收缓冲区,直到缓冲区满后服务端停止发送,但是上层应用已经不会再读取该缓冲区的数据,会造成资源泄漏。


2. HTTP2与HTTP1的超时行为差异

HTTP1.x的请求-响应模型是单流串行,同一个TCP连接同一时间只能处理一个请求,因此超时行为是连接粒度的:

  • 单个请求读取超时会直接销毁整个TCP连接,不会再复用。

HTTP2引入了多路复用机制,单个TCP连接上可以并行跑多个独立的Stream(每个Stream对应一个请求-响应对),因此超时行为是流粒度的:

  • 单个请求读取超时只会向服务端发送RST_STREAM帧关闭对应Stream,不会影响同连接上其他正在处理的请求,整个TCP连接还可以继续复用。
  • 只有连接级别的空闲超时、握手失败、协议错误等全局异常场景下,才会关闭整个TCP连接。
  • 超时Stream后续到达的响应帧会被客户端直接丢弃,不会影响其他Stream的正常数据处理。

内容的提问来源于stack exchange,提问作者Maciej Mościcki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:54:03