艺术设计专业灵感推荐网站,齐家网和土巴兔装修哪家好,现在asp做网站,宜昌平台网站建设TCP 有很多连接状态#xff0c;每一个都够聊十块钱儿的#xff0c;比如我们以前讨论过 TIME_WAIT 和 FIN_WAIT1#xff0c;最近时不时听人提起 CLOSE_WAIT#xff0c;感觉有必要梳理一下。 所谓 CLOSE_WAIT#xff0c;借用某位大牛的话来说应该倒过来叫做 WAIT_CLOSE…TCP 有很多连接状态每一个都够聊十块钱儿的比如我们以前讨论过 TIME_WAIT 和 FIN_WAIT1最近时不时听人提起 CLOSE_WAIT感觉有必要梳理一下。 所谓 CLOSE_WAIT借用某位大牛的话来说应该倒过来叫做 WAIT_CLOSE也就是说「等待关闭」如果你还不理解其含义可以看看 TCP 关闭连接时的图例 TCP Close
不要被图中的 client 和 server 所迷惑你只要记住主动关闭的一方发出 FIN 包被动关闭的一方响应 ACK 包此时被动关闭的一方就进入了 CLOSE_WAIT 状态。如果一切正常稍后被动关闭的一方也会发出 FIN 包然后迁移到 LAST_ACK 状态。
通常CLOSE_WAIT 状态在服务器停留时间很短如果你发现大量的 CLOSE_WAIT 状态那么就意味着被动关闭的一方没有及时发出 FIN 包一般有如下几种可能
程序问题如果代码层面忘记了 close 相应的 socket 连接那么自然不会发出 FIN 包从而导致 CLOSE_WAIT 累积或者代码不严谨出现死循环之类的问题导致即便后面写了 close 也永远执行不到。响应太慢或者超时设置过小如果连接双方不和谐一方不耐烦直接 timeout另一方却还在忙于耗时逻辑就会导致 close 被延后。响应太慢是首要问题不过换个角度看也可能是 timeout 设置过小。BACKLOG 太大此处的 backlog 不是 syn backlog而是 accept 的 backlog如果 backlog 太大的话设想突然遭遇大访问量的话即便响应速度不慢也可能出现来不及消费的情况导致多余的请求还在队列里就被对方关闭了。
如果你通过「netstat -ant」或者「ss -ant」命令发现了很多 CLOSE_WAIT 连接请注意结果中的「Recv-Q」和「Local Address」字段通常「Recv-Q」会不为空它表示应用还没来得及接收数据而「Local Address」表示哪个地址和端口有问题我们可以通过「lsof -i:PORT」来确认端口对应运行的是什么程序以及它的进程号是多少。
如果是我们自己写的一些程序比如用 HttpClient 自定义的蜘蛛那么八九不离十是程序问题如果是一些使用广泛的程序比如 Tomcat 之类的那么更可能是响应速度太慢或者 timeout 设置太小或者 BACKLOG 设置过大导致的故障。
此外还有一点需要说明按照前面图例所示当被动关闭的一方处于 CLOSE_WAIT 状态时主动关闭的一方处于 FIN_WAIT2 状态。 那么为什么我们总听说 CLOSE_WAIT 状态过多的故障但是却相对少听说 FIN_WAIT2 状态过多的故障呢这是因为 Linux 有一个「tcp_fin_timeout」设置控制了 FIN_WAIT2 的最大生命周期。坏消息是 CLOSE_WAIT 没有类似的设置如果不重启进程那么 CLOSE_WAIT 状态很可能会永远持续下去好消息是如果 socket 开启了 keepalive 机制那么可以通过相应的设置来清理无效连接不过 keepalive 是治标不治本的方法还是应该找到问题的症结才对。