tcp timewait closewait 过多情况

TIMEWAIT作用

  1. 为实现TCP全双工连接的可靠释放[最后一个ACK丢失了,被动关闭一方会重发它的FIN,主动关闭一方必须维持一个有效状态信息(TIMEWAIT状态下维持),以便能够重发ACK,否则被动一方会认为有错误产生]
  2. 保证在下一个人使用的IP地址与端口与先前的完全相同的情况下,上一个残留的数据包,不会被下一个人接收到(time_wait持续等待时间为2msl,确保数据丢失成功)。

TIMEWAIT CLOSE_WAIT什么时候过多

如果你的程序设计为服务器主动关闭,那么你才有可能需要关注这个TIMEWAIT状态过多的问题。
1.在生产过程中,如果服务器使用短连接,那么完成一次请求后会主动断开连接,就会造成大量time_wait状态。因此我们常常在系统中会采用长连接,减少建立连接的消耗,同时也减少TIME_WAIT的产生,
2.但实际上即使使用长连接配置不当时,当TIME_WAIT的生产速度远大于其消耗速度时,系统仍然会累计大量的TIME_WAIT状态的连接。TIME_WAIT状态连接过多就会造成一些问题。如果客户端的TIME_WAIT连接过多,同时它还在不断产生,将会导致客户端端口耗尽,新的端口分配不出来,出现错误。如果服务器端的TIME_WAIT连接过多,可能会导致客户端的请求连接失败,这在接下来举例说明。

如果你的服务器设计为被动关闭,那么你首先要关注的是CLOSE_WAIT
close_wait 按照正常操作的话应该很短暂的一个状态,接收到客户端的fin包并且回复客户端ack之后,会继续发送fin包告知客户端关闭关闭连接,之后迁移到Last_ACK状态。但是close_wait过多只能说明没有迁移到Last_ACK,也就是服务端是否发送fin包,只有发送fin包才会发生迁移,所以问题定位在是否发送fin包。fin包的底层实现其实就是调用socket的close方法,这里的问题出在没有执行close方法。说明服务端socket忙于读写。

CLOSEWAIT过多解决办法

基本的思想就是要检测出对方已经关闭的socket,然后关闭它。
1.代码需要判断socket,一旦read返回0,断开连接,read返回负,检查一下errno,如果不是AGAIN(表示现在没有数据稍后重新读取),也断开连接。
2.给每一个socket设置一个时间戳last_update,每接收或者是发送成功数据,就用当前时间更新这个时间戳。定期检查所有的时间戳,如果时间戳与当前时间差值超过一定的阈值,就关闭这个socket。
3.使用一个Heart-Beat线程,定期向socket发送指定格式的心跳数据包,如果接收到对方的RST报文,说明对方已经关闭了socket,那么我们也关闭这个socket。
4.设置SO_KEEPALIVE选项,并修改内核参数

TIMEWAIT过多解决办法

让服务器能够快速回收和重用那些TIME_WAIT的资源这个可以通过改变内核配置做到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章