Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)
1.TCP握手定理
2.TCP状态
l CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”。
l LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接。
l SYN_RCVD :表示服务器接收到了来自客户端请求连接的SYN报文。在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat很难看到这种状态,除非故意写一个监测程序,将三次TCP握手过程中最后一个ACK报文不予发送。当TCP连接处于此状态时,再收到客户端的ACK报文,它就会进入到ESTABLISHED 状态。
l SYN_SENT :这个状态与SYN_RCVD 状态相呼应,当客户端SOCKET执行connect()进行连接时,它首先发送SYN报文,然后随即进入到SYN_SENT 状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT 状态表示客户端已发送SYN报文。
l ESTABLISHED :表示TCP连接已经成功建立。
l FIN_WAIT_1 :这个状态得好好解释一下,其实FIN_WAIT_1 和FIN_WAIT_2 两种状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET进入到FIN_WAIT_1 状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2 状态。当然在实际的正常情况下,无论对方处于任何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1 状态一般是比较难见到的,而FIN_WAIT_2 状态有时仍可以用netstat看到。
l FIN_WAIT_2 :上面已经解释了这种状态的由来,实际上FIN_WAIT_2状态下的SOCKET表示半连接,即有一方调用close()主动要求关闭连接。注意:FIN_WAIT_2 是没有超时的(不像TIME_WAIT 状态),这种状态下如果对方不关闭(不配合完成4次挥手过程),那这个 FIN_WAIT_2 状态将一直保持到系统重启,越来越多的FIN_WAIT_2 状态会导致内核crash。
l TIME_WAIT :表示收到了对方的FIN报文,并发送出了ACK报文。 TIME_WAIT状态下的TCP连接会等待2*MSL(Max Segment Lifetime,最大分段生存期,指一个TCP报文在Internet上的最长生存时间。每个具体的TCP协议实现都必须选择一个确定的MSL值,RFC 1122建议是2分钟,但BSD传统实现采用了30秒,Linux可以cat /proc/sys/net/ipv4/tcp_fin_timeout看到本机的这个值),然后即可回到CLOSED 可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(这种情况应该就是四次挥手变成三次挥手的那种情况)
l CLOSING :这种状态在实际情况中应该很少见,属于一种比较罕见的例外状态。正常情况下,当一方发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING 状态表示一方发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?那就是当双方几乎在同时close()一个SOCKET的话,就出现了双方同时发送FIN报文的情况,这是就会出现CLOSING 状态,表示双方都正在关闭SOCKET连接。
l CLOSE_WAIT :表示正在等待关闭。怎么理解呢?当对方close()一个SOCKET后发送FIN报文给自己,你的系统毫无疑问地将会回应一个ACK报文给对方,此时TCP连接则进入到CLOSE_WAIT状态。接下来呢,你需要检查自己是否还有数据要发送给对方,如果没有的话,那你也就可以close()这个SOCKET并发送FIN报文给对方,即关闭自己到对方这个方向的连接。有数据的话则看程序的策略,继续发送或丢弃。简单地说,当你处于CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。
l LAST_ACK :当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK 状态。当收到对方的ACK报文后,也就可以进入到CLOSED 可用状态了。
#######################################################################################################################################
LISTEN:等待从任何远端TCP 和端口的连接请求。 SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。 SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。 ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。 FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。 FIN_WAIT_2:等待远端TCP 的连接终止请求。 CLOSE_WAIT:等待本地用户的连接终止请求。 CLOSING:等待远端TCP 的连接终止请求确认。 LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认) TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。 TIME_WAIT 两个存在的理由: 1.可靠的实现tcp全双工连接的终止; 2.允许老的重复分节在网络中消逝。 CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)
######################################################################################################################################
3.服务器大量TIME_WAIT和CLOSE_WAIT分析
#查看TCP状态:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1
常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭,Listen表示正在监听可以接受客户端连接。
#常见问题分析
1.服务器保持了大量TIME_WAIT状态
2.服务器保持了大量CLOSE_WAIT状态
因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,tomcat崩溃。
#############################################################################
tomcat环境下服务器文件句柄耗尽(Too Many Open Files)的问题排查
为什么会出现文件句柄耗尽的情况?
主要是因为linux在文件句柄的数目上有两个级别的限制。一个是系统级别的总数限制,一个是针对用户的限制。默认情况下每个用户所能使用的句柄数是1024。一般情况下1024也够用了,但是在大容量的系统上,特别是会频繁使用网络通信和文件IO的系统上,1024很快就被耗光了。所以首先我们要调整这个值。修改方法如下:
1. ulimit -a 查看当前用户的文件句柄限制
2. 用户级别的句柄数限制修改
修改 /etc/security/limits.conf 增加下面的代码:
用户名(或者用*表示所有用户) soft nofile 65535
用户名 hard nofile 65535
有两种限制,一种是soft软限制,在数目超过软限制的时候系统会给出warning警告,但是达到hard硬限制的时候系统将拒绝或者异常了。
修改之后可能需要重启shell生效。
3. 系统级别的句柄数限制修改
sysctl -w fs.file-max 65536
或者 echo "65536" > /proc/sys/fs/file-max
两者作用是相同的,前者改内核参数,后者直接作用于内核参数在虚拟文件系统(procfs, psuedo file system)上对应的文件而已。
可以用下面的命令查看新的限制
sysctl -a | grep fs.file-max
或者 cat /proc/sys/fs/file-max
4.修改内核参数
/etc/sysctl.conf
echo "fs.file-max=65536" >> /etc/sysctl.conf
sysctl -p
查看系统总限制 命令:cat /proc/sys/fs/file-max
查看整个系统目前使用的文件句柄数量命令:cat /proc/sys/fs/file-nr
查看某个进程开了哪些句柄 :lsof -p pid
某个进程开了几个句柄 :lsof -p pid |wc -l
也可以看到某个目录 /文件被什么进程占用了,显示已打开该目录或文件的所有进程信息 :lsof path/filename
具体这个值应该设置成多少?
优先级(Open File Descriptors):
soft limit < hard limit < kernel < 实现最大file descriptor数采用的数据结构所导致的限制
其实这个值倒是没有具体限制,但是分配的值如果太大反而会影响系统性能,所以要根据具体应用调配权衡。
问题的解决方案:
首先当然是修改linux句柄数限制到一个合适的值。
然后就是应用本身的一个调整。有这么几种情况:
1.数据库连接池的优化。必须要使用连接池,否则句柄没耗光数据库就崩了。。。
2.抓取资源的时候有可能会用到HttpClient,尽量也应该使用连接池来控制连接数。
3.连接池设置的把握,建立连接超时时间,读取超时时间,连接数目,等待时间,等都需要配置到一个合适的值,否则发挥不出连接池的性能。
###########################################################################################################
解决思路很简单,就是让服务器能够快速回收和重用那些TIME_WAIT的资源。
对/etc/sysctl.conf文件的修改:
#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
net.ipv4.tcp_syn_retries=2
#net.ipv4.tcp_synack_retries=2
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
net.ipv4.tcp_keepalive_time=1200
net.ipv4.tcp_orphan_retries=3
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
net.ipv4.tcp_fin_timeout=30
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 4096
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 1
##减少超时前的探测次数
net.ipv4.tcp_keepalive_probes=5
##优化网络设备接收队列
net.core.netdev_max_backlog=3000
net.ipv4.tcp_fin_timeout
net.ipv4.tcp_keepalive_*
如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码。因为问题出在服务器程序里头啊。
转载于:https://www.cnblogs.com/xinfang520/p/8961129.html
Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)相关推荐
- TCP状态中 time_wait 的作用?
TCP状态中 time_wait 的作用 前言 这么做有两个理由 前言 客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间. ...
- linux关闭established状态,有关ESTABLISHED,CLOSE_WAIT,TIME_WAIT等连接状态
在Linux的日常维护过程中,会经常用到下面的命令: netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 它会显示 ...
- close wait 过多原因_干货分享!服务端 TCP 连接的 TIME_WAIT 问题分析与解决
写在开头,大概 4 年前,听到运维同学提到 TIME_WAIT 状态的 TCP 连接过多的问题,但是当时没有去细琢磨:最近又听人说起,是一个新手进行压测过程中,遇到的问题,因此,花点时间,细深究一下. ...
- 83998 连接服务器出错_服务端 TCP 连接的 TIME_WAIT 问题分析与解决
民工哥技术之路 写在开头,大概 4 年前,听到运维同学提到 TIME_WAIT 状态的 TCP 连接过多的问题,但是当时没有去细琢磨:最近又听人说起,是一个新手进行压测过程中,遇到的问题,因此,花点时 ...
- linux查看tcp连接日志,linux下tcp状态是从哪查出来的
linux中,各种tcp连接的状态存储在 /proc/net/tcp 文件中 其中st列就是tcp的各种状态,那么这个值代表什么意思呢? 有网友从内核源码里找到了这个 enum { TCP_ESTAB ...
- Linux笔记-centos中大量tcp状态为TIME_WAIT
这里主要主要原因是,我这边有个神器的硬件,时不时都断开一下.然后我搞了个重连的机制,运行一晚上发现大量的TIME_WAIT vi /etc/sysctl.conf 编辑文件,加入以下内容: net.i ...
- 解决Linux服务器中TCP的FIN_WAIT2,CLOSE_WAIT状态连接过多的问题
问题现象 Linux系统服务器中FIN_WAIT2,CLOSE_WAIT状态的TCP链接过多,服务不能及时响应. 通过命令 netstat –ant|grep FIN_WAIT2|wc –l 查看连接 ...
- Linux 查看tcp 请求 中 的各个 状态 数据 ,如timewait
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}' ...
- TCP连接中TIME_WAIT连接过多
2019独角兽企业重金招聘Python工程师标准>>> TCP连接中TIME_WAIT连接过多 转载于:https://my.oschina.net/meowmeow/blog/36 ...
最新文章
- OpenCV-Python我刚写六行代码就出了个惊天BUG
- python range()内建函数
- HealthKit开发教程之HealthKit的复合数据
- 避无可避:Mesos安全问题的几点思考
- 将SimCLR应用于NLP预训练模型,提升句子语义表征效果
- Streaming 101
- 20171213-python自动化-接口测试-jmeter-get-设置header
- win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?...
- iOS中将后台JSON数据转化为模型的总结
- k2p官方改版固件v2.2
- Sqlite字段长度填坑
- 图片和边框的距离调整html,css图片如何设置上边框距离
- 最新kali之medusa
- windows10升级助手_Win7即将全面停更,看这里,决定回退还是升级?
- linux 查看nas磁盘阵列,NAS(linux)阵列管理
- 国产FPGA市场格局及进展
- 生成网站与发布网站的区别
- 实现keras中ConvLSTM2D中recurrent_activation和activation的设置
- sqoop的java操作,总结归纳,含代码
- 一文弄懂原子性、临界区、临界资源
热门文章
- 华中师范大学邮箱matlab,18春[华中师范大学]华师《Matlab基础与应用》在线作业1(100分)...
- php如何与数据库连接,PHP文章如何和数据库连接(1)
- java tm无响应_Java(TM) Platform SE binary 未响应 是怎么个情况?
- flex java 开发环境搭建_Flex+JAVA+BlazeDS开发环境配置(Java工程和Flex工程独立)
- STM32F1笔记(七)WWDG窗口看门狗
- c++ cdi+示例_C ++“和”关键字示例
- 基于云平台的家居综合监测管理系统的设计与实现
- 实验6 数据查询--高级查询
- 深入理解linux系统下proc文件系统内容
- ubuntu下修复U盘只读问题