专栏首页不想当开发的产品不是好测试TCP time_wait close_wait问题(可能是全网最清楚的例子)

TCP time_wait close_wait问题(可能是全网最清楚的例子)

背景

公司群里,运维发现一个问题,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个包。

  • 第一次:客户端发送初始序号x和syn=1请求标志
  • 第二次:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1
  • 第三次:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1

四次挥手

TCP连接断开需要经过四次挥手; 通俗版本: 前提A和B在通话 A:好的,我的话就说完了(FIN); B:哦哦,我知道你说完啦(ACK),我还有说两句哈;A: (没说话,一直听着) B:哦了,我也说完了(FIN) A:好的,我也知道你说玩了(ACK),挂电话吧

专业版本:

  • 第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态
  • 第二次挥手:服务器收到客户端的后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE-WAIT状态
  • 第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态。此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号seq=w,服务器进入LAST-ACK(最后确认态)
  • 第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态。

状态流转图

实际例子

建立连接

linux上起了一个redis服务

本地起的6379端口

还是同一台机器上,通过python脚本连接该redis服务:

此时网络连接如下:

关注这两个网络连接,第一个是redis-server的,第二是python脚本的,此时都是ESTABLISHED状态,表示这两个进程建立了连接

TIME_WAIT情况

现在断掉python

之前的python的那个连接,是TIME_WAIT状态 客户端(主动方)主动断开,进入TIME_WAIT状态,服务端(被动方)进去CLOSE状态,就是没有显示了

等待2MSL(1分钟)后,如下:

TIME_WAIT状态的连接也消失了,TIME_WAIT回收机制,系统ing过一段时间会回收,资源重利用

CLOSE_WAIT情况

先建立连接,如下:

关掉redis服务,service redis stop

之前的redis-server的45370端口连接 进入了FIN_WAIT2状态,而python端(被动关闭方)就进去了CLOSE_WAIT状态

等待30s后,在看连接

只有python的那条CLOSE_WAIT

再次操作python端的脚本,再次get

关于6379端口(redis端口)的网络连接都没有了

TCP参数设置

如何快速回收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使之生效

经验之谈

个人经验,不一定对,如有错误,请指正

  1. 当出现了CLOSE_WAIT大概率是业务代码问题,代码中没有处理服务异常的情况,如上面的例子,python再次请求redis的时候,发现redis挂了,就会主动干掉CLOSE_WAIT状态
  2. 出现大量TIME_WAIT的情况,一般是服务端没有及时回收端口,linux内核参数需要调整优化

参考资料

https://www.mobibrw.com/2019/20477

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python安装mysql-python依赖包

    新公司,对换工作了!接口自动化使用的是python的behave框架,因此需要折腾python了,而公司配的笔记本是windows的,因此要在windows下折...

    千往
  • jenkins 后台程序运行

    # 背景 jenkins持续集成,需要任务后台执行(nohup执行)结果发现jenkins的job执行完后,看不到运行的进程 # 步骤 原因就是这么一个情况:J...

    千往
  • centos下安装python3

    前言 本文操作基本参考下面的文章,因此直说几个关键点,大家阅读这篇文章的话,跳转到原作者那里去吧 原作者: ehlxr 原文链接: https://ehlxr....

    千往
  • locust使用经验---每个任务使用新

    测试工具选用locust,locust中文意思为蝗虫,可以想象,locust就像成片的蝗虫,扑向我们的服务。

    用户2398817
  • 微软远程桌面[Remote Desktop Client]连接问题解决..

    最近工作电脑升级了Windows 1o,免费帮微软测试.. 但是发现远程桌面无法连接这台电脑了.. 通常我把工作的PC作为服务器,使用Mac 的RDC连接w...

    gigiwangs
  • Identity Server 4 - Hybrid Flow - 使用ABAC保护MVC客户端和API资源

    这个系列文章介绍的是Identity Server 4 实施 OpenID Connect 的 Hybrid Flow. 

    solenovex
  • 10.6 Git 内部原理 - 传输协议

    Git 可以通过两种主要的方式在版本库之间传输数据:“哑(dumb)”协议和“智能(smart)”协议。 本节将会带你快速浏览这两种协议的运作方式。

    shaonbean
  • 使用plsql developer连接oracle数据库

    需要在服务器上安装服务端数据库 本机上安装数据库的客户端及plsql 修改oraname.ora

    城市中的游牧民族
  • Linux下开启FTP的21端口

    这几天一直在学习在CentOS7.0创建本地yum源和局域网yum源,准备两台CentOS7.0虚拟机,一个做服务器,一个做客户端;由于开发环境只有局域网,没法...

    麦克劳林
  • 准备好纸和笔,人肉计算比特币:每天0.67哈希值

    在这篇文章中,我们一起来看一看用纸和笔来人肉“挖”比特币的难度到底有多大。 实际上,用于挖矿的SHA-256算法其实还算是比较简单的了,而且可以手工计算出来。毫...

    FB客服

扫码关注云+社区

领取腾讯云代金券