昨天写了一篇文章介绍了close_WAIT ,有个粉丝说我没有讲到到问题的关键,因为在实际项目中,我们关心的是如果服务器保持了大量的CLOSE_WAIT应该怎么解决。说的也是,因为在具体的项目开发过程中,面对PM ,面对项目Schedule ,快速的重现问题、定位问题、解决问题才是王道。
CLOSE_WAIT产生的原因
CLOSE_WAIT这个称呼其实并不好,或者说不形象,更确切的说应该叫WAIT_CLOSE .
因为CLOSE_WAIT产生的原因在于:TCP server 已经ACK了过来的FIN数据包,但是上层应用程序迟迟不确认要去关闭到client 端的连接。所以TCP一直在那等啊等.....
这个时候TCP就好比是干活的小弟,上层应用就好比是做决定的领导,领导没有发命令要去close到client端的连接,作为小弟的TCP 只能wait_close 指令。
那么问题来了,上层应用这个领导是谁,这个领导为什么不发指令告诉TCP 去发送FIN包以断开连接。
这个上层应用就是我们软件工程师自己写的server 端。我去,怎么感觉自己跳到了自己刨的坑里面了.....
所以说如果你发现自己的服务器保持了大量的CLOSE_WAIT,问题的根源十有八九是你自己的server端程序的问题。
自己从自己刨的坑里跳出来
这里我分享自己在之前搭建的一个server 保持了大量的的CLOSE_WAIT的解决方法。
问题描述
开始的时候是发现自己搭建的server 运行一段时间以后就ping 不通了,客户端也连接不上了,最后发现是server端有大量的CLOSE_WAIT状态的tcp pcb ,至于怎么发现的你就不要问了,我说过了我不是TCP/IP高手,发现问题是一个痛苦的过程
原因分析
我的系统运行的是FreeRTOS操作系统的 ,TCP协议作为FreeRTOS一个Task运行,TCP/IP协议栈的优先级并不高,这个其实也不是最主要的,最最要的是其他Task中,有个Task会频繁的周期性的访问临界资源,说到这里估计高手们应该都看出门道了,是的,临界资源保护会屏蔽软件中断,协议栈线程受系统调度的影响,以至于server的应用程序不能实时响应网络上连接处理。
解决方法
修改TCP/IP任务优先级,从而确保网络任务的实时响应
扩大临界资源访问周期,确切的说是减少临界资源的访问,从而能够让TCP/IP任务获得更多的CPU运行权限。
这样修改以后,问题就没了。对程序员来说,解掉一个棘手的bug ,有一种奥特曼打怪兽的感觉。