你用浏览器打开一个网页,页面加载完后,浏览器和服务器之间的连接是不是立刻就断了?其实不一定。很多情况下,这个连接会继续留着,等几秒甚至几十秒,为下一次请求“省点劲”——这就是长连接(Keep-Alive)。
长连接不是服务器单方面决定的
很多人以为只要服务器开了 Keep-Alive,客户端就自动用上了。其实不然。HTTP 协议里,长连接需要客户端和服务端双方都同意。客户端在发起请求时,得明确告诉服务器:“我支持长连接,请别急着关掉连接。”
怎么告诉?靠的是请求头里的 Connection: keep-alive 字段。比如你在 Chrome 开发者工具的 Network 标签下随便点一个资源,点开 Headers,就能看到这一行:
Connection: keep-alive现代主流浏览器(Chrome、Firefox、Edge、Safari)默认都会带上这行,也就是说,它们默认支持并启用长连接。不用你手动设置,也不用装插件。
那命令行工具呢?curl 和 wget 怎么样?
curl 默认也开启 Keep-Alive,只要你没加 --no-keepalive 参数。执行下面这行命令,抓包一看,请求头里就有 Connection: keep-alive:
curl -v https://example.comwget 稍微保守一点,默认不复用连接,但加个 --keep-alive 就行:
wget --keep-alive https://example.com自己写代码发请求,要注意什么?
如果你用 Python 的 requests 库,放心,它默认走长连接。底层 urllib3 会自动管理连接池,重复请求同一个域名时,大概率复用旧 TCP 连接。
Node.js 的 http.request 默认也是开启 Keep-Alive 的,但要注意:必须手动设置 headers.Connection = 'keep-alive',否则某些老版本或自定义 Agent 可能不会带这个头。
Java 的 HttpURLConnection 在 JDK7+ 默认启用 Keep-Alive;Go 的 net/http 客户端也默认复用连接,只要你不显式关闭。
不支持长连接的客户端,现在还有吗?
极少见了。上世纪末的 IE5、Netscape 4.x 或某些嵌入式设备的简易 HTTP 客户端可能只支持 HTTP/1.0 且不带 Connection 头,这种就是短连接——发完一个请求,立马断开。但现在连 IoT 设备 SDK 基本都默认兼容 HTTP/1.1 和 Keep-Alive。
真正影响是否走长连接的,反而是服务端配置。比如 Nginx 默认开启 keepalive_timeout 75s,但如果你的后端 PHP-FPM 或 Tomcat 把连接池设得太小,或者中间有代理强行改写了 Connection 头,那客户端再支持也没用。
怎么验证当前请求用了长连接?
最直接的方法是看响应头有没有 Connection: keep-alive,再配合抓包工具(如 Wireshark 或 Chrome 的 Network → Timing 选项卡)。如果“Connection ID”在多次请求中没变,或者“Waiting (TTFB)”时间明显变短,基本可以判断连接被复用了。