外观
一句话答案
主动关闭方进入 TIME_WAIT 等 2MSL,确保最后 ACK 到达且旧报文消亡;高并发短连接时大量 TIME_WAIT 需优化。
核心要点
TIME_WAIT:
- 发生在主动关闭方(通常是客户端),发出第4次 ACK 后进入
- 等待时间:2MSL(Maximum Segment Lifetime,报文最大存活时间,Linux 默认约 60s)
为什么要等 2MSL:
- 保证最后一个 ACK 能到达对方:若 ACK 丢失,服务端会重发 FIN;2MSL 内可以重新响应
- 让网络中残留的旧报文消失:防止旧连接的延迟报文被新连接误接收
TIME_WAIT 过多的问题:
- 大量 TIME_WAIT 占用端口(每个 TIME_WAIT 占用一个四元组),可能耗尽可用端口
- 高并发短连接场景(如 HTTP/1.0)容易出现
解决:
bash
# Linux 内核参数
net.ipv4.tcp_tw_reuse = 1 # 允许 TIME_WAIT socket 用于新连接(需满足条件)
net.ipv4.tcp_fin_timeout = 30 # 减少 FIN_WAIT_2 等待时间CLOSE_WAIT:
- 发生在被动关闭方(服务端),收到对方 FIN 后发出 ACK,等待本地应用程序关闭连接
出现大量 CLOSE_WAIT 的根本原因:
- 服务端代码没有调用
socket.close(),即连接没有被正确关闭
常见代码原因:
java
// 错误:没有在 finally 中关闭连接
try {
InputStream in = socket.getInputStream();
// 处理数据
} catch (Exception e) {
log.error(e);
// ❌ 没有 close!
}
// 正确:
try (Socket socket = ...) { // try-with-resources 自动关闭
...
}排查方法:
bash
netstat -an | grep CLOSE_WAIT | wc -l # 统计 CLOSE_WAIT 数量
# 大量 CLOSE_WAIT → 检查服务端代码是否有资源未关闭(连接池泄漏)追问与易错
追问方向:
- TIME_WAIT 过多怎么优化?
- 2MSL 具体是多久?
- tcp_tw_reuse 安全吗?
易错点:
- ❌ TIME_WAIT 是异常状态——是正常的 TCP 关闭流程
- ❌ 直接设 tcp_tw_recycle——在 NAT 环境会导致连接异常
💡 记忆锚点
TIME_WAIT像退房后酒店保留房卡2小时(2MSL):一是防你落了东西回来取(最后ACK丢了对方重发FIN),二是等前一位客人的外卖别送到新客人手上(旧报文消亡)。高并发短连接场景TIME_WAIT太多会耗尽端口,用tcp_tw_reuse允许复用。CLOSE_WAIT过多则是服务端忘了关门(没调close)。