工程实践

  • 服务端优雅关闭连接一般怎么做?
    停止接受新请求(停止 accept/摘除负载均衡),等待在途请求完成;对已建立连接先 shutdown(SHUT_WR) 发送 FIN,继续读对端残留数据直到 recv 返回 0,再 close 释放;必要时设置超时以防无限等待。

  • 什么时候应该由服务端主动 close?
    协议业务完成且不再需要保持连接、遇到不可恢复错误/协议异常、空闲超时/慢请求超时、上游下线维护时需要快速退连接。

  • 长连接服务如何避免 CLOSE_WAIT?
    在读循环中正确处理 recv=0 立即关闭;对每个连接使用 RAII/作用域封装,确保异常路径也 close;为连接设置读取/写入超时或 idle 超时;开启 TCP keepalive 或应用心跳及时发现对端死亡,防止线程阻塞。

  • 短连接服务如何控制 TIME_WAIT?
    尽量让客户端作为主动关闭方(服务端被动收 FIN);能复用就复用连接或批量请求,减少短连;如必须大量主动外连,可使用连接池、增加源 IP/端口(SO_REUSEPORT/多 IP),谨慎调低 tcp_fin_timeout 或启用 tcp_tw_reuse(仅主动发起侧)。

  • 负载均衡 / 反向代理会影响挥手吗?
    会。LB/代理可能有自己的空闲超时和健康检查,会主动发 FIN/RST 断开后端连接;TCP 状态在每一跳独立存在,TIME_WAIT/CLOSE_WAIT 可能出现在客户端-LB、LB-后端两段而非直连。

  • keepalive 能否避免挥手问题?
    不能。TCP keepalive/应用心跳只是尽早发现死连接,仍需正常 FIN 握手或超时后 RST 释放资源;它无法替代关闭流程,只是减少僵尸连接积累。