在TCP协议中,当客户端主动关闭连接时,TCP会进入TIME_WAIT状态,该状态会持续2MSL(最大报文生存时间)。在TIME_WAIT状态下,TCP会继续维护连接信息,用于处理网络延迟导致的异常报文。
TIME_WAIT状态会导致一些问题,比如服务器重启时会占用大量端口等。处理TIME_WAIT状态主要有以下几种方式:
- 降低MSL值:减少TIME_WAIT状态时间,但可能导致异常报文处理失败。
# Linux下调整MSL
sysctl -w net.ipv4.tcp_fin_timeout=30
- 设置重用端口:允许在TIME_WAIT状态重用端口,需要注意避免异常报文干扰新连接。
serverSocket.setReuseAddress(true);
- 轮询查找可用端口:不断尝试不同端口直到找到可用的。
int port;
do {
port++;
serverSocket = new ServerSocket(port);
} while (serverSocket.getChannel().socket().isBound());
- 设置延迟接受:defer accept,推迟接收新的连接请求,让TIME_WAIT状态超时。
serverSocket.setSoTimeout(1000); // 1s超时
serverSocket.accept();
- 设置最大连接数:限制系统级连接数,让TIME_WAIT状态连接关闭,释放资源。
# Linux下设置最大连接数
sysctl -w net.ipv4.tcp_max_syn_backlog=1024
一般推荐优先使用设置重用端口和轮询查找可用端口的方式处理TIME_WAIT问题。降低MSL值和设置最大连接数的方式可能会对系统稳定性产生一定影响。
延迟接受方式在繁忙时可能会出现连接超时,需要注意。