公司群里,运维发现一个问题,task服务报错(如下)
The stream or file \"/data/logs/adn_task/offer_service.log\" could not be opened:
failed to open stream: Too many open files
测试老大看到了,根据经验就推测是应该是文件句柄使用完了,应该有TCP连接很多没释放,果真发现是很多CLOSE_WAIT的状态
短链接,一次链接就会占用一个端口,一个端口就是一个文件描述符; 文件描述符 又称 句柄,linux系统最大的句柄数是65535,可以通过ulimit -a 查看
TCP建立连接需要经过三次握手; 通俗版本: A: 你好,你能听见我说话吗? B: 能听到,你能听到我说话吗? A:我也能听到,我们开始通信吧
专业版本: 建立TCP连接时,需要客户端和服务器共发送3个包。
TCP连接断开需要经过四次挥手; 通俗版本: 前提A和B在通话 A:好的,我的话就说完了(FIN); B:哦哦,我知道你说完啦(ACK),我还有说两句哈;A: (没说话,一直听着) B:哦了,我也说完了(FIN) A:好的,我也知道你说玩了(ACK),挂电话吧
专业版本:
linux上起了一个redis服务
本地起的6379端口
还是同一台机器上,通过python脚本连接该redis服务:
此时网络连接如下:
关注这两个网络连接,第一个是redis-server的,第二是python脚本的,此时都是ESTABLISHED状态,表示这两个进程建立了连接
现在断掉python
之前的python的那个连接,是TIME_WAIT状态 客户端(主动方)主动断开,进入TIME_WAIT状态,服务端(被动方)进去CLOSE状态,就是没有显示了
等待2MSL(1分钟)后,如下:
TIME_WAIT状态的连接也消失了,TIME_WAIT回收机制,系统ing过一段时间会回收,资源重利用
先建立连接,如下:
关掉redis服务,service redis stop
之前的redis-server的45370端口连接 进入了FIN_WAIT2状态,而python端(被动关闭方)就进去了CLOSE_WAIT状态
等待30s后,在看连接
只有python的那条CLOSE_WAIT了
再次操作python端的脚本,再次get
关于6379端口(redis端口)的网络连接都没有了
如何快速回收TIME_WAIT和FIN_WAIT /etc/sysctl.conf 包含以下配置项 net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30 root权限 执行/sbin/sysctl -p使之生效
个人经验,不一定对,如有错误,请指正