图 1:本文封面,点明长短连接的成本对比与保活主题。
先说明属性:这是一篇经典题解析,题目出自本地历史面试资料,与任何公司的当前招聘无关。「长连接和短连接」听起来像常识题,但面试官的给分点在第二层:成本差异你能算清,保活机制你分不清 HTTP 层和 TCP 层,就露底了。
想象一个典型场景:你的服务每天被上游调用上亿次,每个请求都新建 TCP 连接,握一次手、传一次数据、挥四次手。面试官问:这套开销占了多少?能不能省?
核心结论:连接成本的本质,是把「建连与释放的固定开销」摊到多少次请求上。
短连接每个请求都要付出完整的一次 TCP 三次握手加四次挥手,外加慢启动的冷连接代价——TCP 连接刚建立时发送速率是爬坡的,短连接永远在用爬坡那段。长连接一次建连反复收发,把固定开销摊薄到成百上千次请求上,连接还能「焐热」。但天下没有免费的连接:长连接要占服务端的文件描述符和内存,空挂着也是成本,海量客户端长挂在服务端就是一场资源灾难。
选型口径因此很清晰。
请求频率高、要求实时、双端相对固定——选长连接,典型如大模型流式输出(SSE、WebSocket)、即时通讯、数据库连接池。客户端量极大而请求稀疏——短连接更省资源,典型如监控打点上报、一次性回调。顺带补一层历史:HTTP/1.0 默认短连接,每个请求一条连接;HTTP/1.1 起默认持久连接,不再逐请求建连。所以「长短连接」在今天的互联网服务里,多数已经不是 HTTP 层的取舍,而是长连接服务的保活设计问题。
保活机制必须分两层说,混在一起是这道题最大的坑。
第一层是 TCP Keep-Alive,内核层的探测。RFC 1122 写得很明确:keep-alive 必须由应用显式开启、默认关闭,而且探测间隔默认不得小于两小时。两小时才发现死连接,对业务毫无意义——它只能兜底清理「对端机器已经没了」的半开连接,救不了你的在线服务。
第二层是应用层心跳,业务自己定期发一个小包,常见做法是每 30 到 60 秒一次 ping/pong(经验值,按链路上最短的 idle 超时来定)。它解决两件事:一是让中间的 NAT、防火墙、负载均衡器别把长时间无流量的映射回收掉;二是秒级发现对端掉线,马上重连,而不是等下一次发数据才报错。
落到实际案例。
大模型流式输出是长连接的教科书场景:一次生成几十秒,token 逐段下发。网关与推理实例之间如果没有应用层心跳,模型「思考」停顿的几十秒里,链路上任何一环的 idle 超时都可能把连接掐掉,用户看到的就是「回答到一半断了」。工程上的标准配置是:SSE 通道每 15 到 30 秒发一个注释心跳行,网关空闲超时放宽到分钟级,客户端检测到心跳中断立即重连并补上下文。
心跳周期没有标准值,原则只有一条:比链路上最短的 idle 超时更短,并留出余量。先把网关、负载均衡、NAT 各环节的空闲回收时间摸清楚,取最小值的一半左右,就是安全区间。
图 2:长短连接成本对比与双层保活机制。
常见误区。
一,把 HTTP 的 Keep-Alive 头和 TCP 的 keep-alive 混为一谈:前者是应用层「这条连接我还要复用」的约定(HTTP/1.1 默认持久连接),后者是内核层的死连接探测,两者只是名字像。二,以为开了 TCP keep-alive 就有了保活——两小时默认间隔救不了任何实时业务。三,以为长连接一旦建立就永远活着:NAT 映射老化、网关重启、对端崩溃,每一条都能无声杀死它。所以「长连接 = 连接 + 心跳 + 重连」,三件套缺一不可。
答题建议。
先给选型口径(请求频率与实时性决定长短),再算成本账(握手挥手摊销 vs 服务端占用),最后把保活拆成内核层与应用层两层,各说职责与参数。这套结构答下来,面试官至少能确认:你维护过长连接服务,而不是背过名词。
你维护过的长连接服务里,踩过最隐晦的连接中断是哪一次?是 NAT 老化、网关超时还是别的原因?欢迎分享。