close_wait(close_wait数量过高 java)
TIME_WAIT和CLOSE_WAIT状态区别
在服务器的日常维护过程中,会经常用到下面的命令:
它会显示例如下面的信息:
常用的三个状态是: ESTABLISHED 表示正在通信, TIME_WAIT 表示主动关闭, CLOSE_WAIT 表示被动关闭。
TIME_WAIT
CLOSE_WAIT
为什么需要 TIME_WAIT 状态?
为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
如果服务器出了异常,百分之八九十都是下面两种情况:
关于网络连接CLOSE_WAIT状态的问题
在开发网络服务器应用系统的时候,有时会碰到服务器有大量的socket处于CLOSE_WAIT状态,也无法关闭,导致服务器无法接受新的用户请求,最终导致服务器奔溃,系统重启才能解决。
为什么会出现大量的CLOSE_WAIT状态呢?
要解决这个问题,我们得先介绍一下socket断开过程中的四次挥手。
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。
假设终止命令由client端发起。
当clien端传输完成数据,或者需要断开连接时:
两个基本问题:
至此似乎明白了为什么会出现CLOSE_WAIT的状态:如果Server端一直没有向client端发送FIN消息(调用close() API),那么这个CLOSE_WAIT会一直存在下去。
从上面我们看到出现CLOSE_WAIT,说明Server端没有发起close()操作,这基本上是用户server端程序的问题了;通常情况下,Server都是等待Client访问,如果Client退出请求关闭连接,server端自觉close()对应的连接。
当然这也可能是业务实现上的需要,暂时不发送FIN,因为服务器可能还有数据要发往客户端,等发送完所有应用数据最后再发送FIN消息了;这个场景并不是这里我们讨论的大量COLSE_WAIT的问题了,因为这个还是可控的。
我们要讨论的场景是什么?我们先介绍两个系统调用,前面也提到并且用到的close(socket)和shutdown(socket,HOW)接着往下分析。
我们知道一个进程打开一个socket,然后此进程fork出子进程的时候,父进程已打开的socket是会被继承的,即子进程能够继续访问这个socket。其结果就是,一个socket被两个进程打开,一个父进程和一个子进程,此时socket的引用计数会变成2。
据此分析,很大可能性是用户服务器的程序实现有问题导致的大量CLOSE_WAIT的socket,比如父进程打开了socket,然后通过fork出子进程来处理业务,父进程继续对网络请求进行监听,永远不会终止;当客户端发FIN过来的时候,处理业务的子进程处理此FIN消息,调用close()对本端进行关闭,然而这个close()调用只是把socket的引用计数器减1,因为父进程还在运行,socket并没关闭,这样就导致系统中又多了一个CLOSE_WAIT的socket,长此以往,就这样了。
多说两句关于TIME_WAIT的状态,这个发生在client端,而且是不可避免的,其时间长度是固定的2MSL,到期自动转为CLOSED,不会导致系统资源耗尽的问题。
MSL是一个系统级参数,可调。
如何手动关闭close_wait
手动关闭close_wait步骤如下:
1、打开一个工作样表作为例子。
2、close是指关闭工作薄,在excel中的操作就是指退出工作薄。对工作薄发生了修改或者创建的工作,那么excel会提示我们去保存修改动作。
3、关闭工作薄对象必须指定激活对象。
4、close方法会检查工作薄的save属性,save属性为TRUE,那么close会自动执行save属性的设置,而忽略自身的参数设置,直接保存后退出。
服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
在日常的服务器维护中,会经常用到如下命令。
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
它会显示例如下面的信息:
TIME_WAIT 689
CLOSE_WAIT 2
FIN_WAIT1 1
ESTABLISHED 291
SYN_RECV 2
LAST_ACK 1
常用的三个状态是:ESTABLISHED表示正在通信 、TIME_WAIT表示主动关闭、CLOSE_WAIT表示被动关闭。
如果服务器出现了异常,很大的可能是出现了以下两种情况:
我们也都知道Linux系统中分给每个用户的文件句柄数是有限的,而TIME_WAIT和CLOSE_WAIT这两种状态如果一直被保持,那么意味着对应数目的通道(此处应理解为socket,一般一个socket会占用服务器端一个端口,服务器端的端口最大数是65535)一直被占用,一旦达到了上限,则新的请求就无法被处理,接着就是大量Too Many Open Files异常,然后tomcat、nginx、apache崩溃。。。
下面来讨论这两种状态的处理方法,网络上也有很多资料把这两种情况混为一谈,认为优化内核参数就可以解决,其实这是不恰当的。优化内核参数在一定程度上能解决time_wait过多的问题,但是应对close_wait还得从应用程序本身出发。
这种情况比较常见,一般会出现在爬虫服务器和web服务器(如果没做内核参数优化的话)上,那么这种问题是怎么产生的呢?
从上图可以看出time_wait是主动关闭连接的一方保持的状态,对于爬虫服务器来说它自身就是客户端,在完成一个爬取任务后就会发起主动关闭连接,从而进入time_wait状态,然后保持这个状态2MSL时间之后,彻底关闭回收资源。这里为什么会保持资源2MSL时间呢?这也是TCP/IP设计者规定的。
TCP要保证在所有可能的情况下使得所有的数据都能够被正确送达。当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状 态,而被动关闭一方则转入CLOSED状态,这的确能够保证所有的数据都被传输。当一个socket关闭的时候,是通过两端四次握手完成的,当一端调用 close()时,就说明本端没有数据要发送了。这好似看来在握手完成以后,socket就都可以处于初始的CLOSED状态了,其实不然。原因是这样安 排状态有两个问题, 首先,我们没有任何机制保证最后的一个ACK能够正常传输,第二,网络上仍然有可能有残余的数据包(wandering duplicates),我们也必须能够正常处理。
TIMEWAIT就是为了解决这两个问题而生的。
再引用网络中的一段话:
time_wait问题可以通过调整内核参数和适当的设置web服务器的keep-Alive值来解决。因为time_wait是自己可控的,要么就是对方连接的异常,要么就是自己没有快速的回收资源,总之不是由于自己程序错误引起的。但是close_wait就不一样了,从上图中我们可以看到服务器保持大量的close_wait只有一种情况,那就是对方发送一个FIN后,程序自己这边没有进一步发送ACK以确认。换句话说就是在对方关闭连接后,程序里没有检测到,或者程序里本身就已经忘了这个时候需要关闭连接,于是这个资源就一直被程序占用着。这个时候快速的解决方法是:
注:
直到写这篇文章的时候我才完全弄明白之前工作中遇到的一个问题。程序员写了爬虫(php)运行在采集服务器A上,程序去B服务器上采集资源,但是A服务器很快就发现出现了大量的close_wait状态的连接。后来手动检查才发现这些处于close_wait状态的请求结果都是404,那就说明B服务器上没有要请求的资源。
下面引用网友分析的结论:
服 务器A是一台爬虫服务器,它使用简单的HttpClient去请求资源服务器B上面的apache获取文件资源,正常情况下,如果请求成功,那么在抓取完 资源后,服务器A会主动发出关闭连接的请求,这个时候就是主动关闭连接,服务器A的连接状态我们可以看到是TIME_WAIT。如果一旦发生异常呢?假设 请求的资源服务器B上并不存在,那么这个时候就会由服务器B发出关闭连接的请求,服务器A就是被动的关闭了连接,如果服务器A被动关闭连接之后程序员忘了 让HttpClient释放连接,那就会造成CLOSE_WAIT的状态了。
close wait什么意思
close wait在英文中我们很少看到,但它却确确实实地存在着,它的意思是什么呢?下面是我给大家整理的close wait什么意思,供大家参阅!
close wait什么意思
等待结束
TIME WAIT和CLOSE WAIT状态区别
在服务器的日常维护过程中,会经常用到下面的命令:
它会显示例如下面的信息:
[plain] view plain copy
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 表示被动关闭。
TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT。
TIME_WAIT
TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。主要是防止最后一个ACK丢失。 由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接
CLOSE_WAIT
CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。
为什么需要 TIME_WAIT 状态?
假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。
为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。
TIME_WAIT 和CLOSE_WAIT状态socket过多
如果服务器出了异常,百分之八九十都是下面两种情况:
1.服务器保持了大量TIME_WAIT状态
2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。
因为Linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,Tomcat崩溃。
netstat listening close wait established等是什么意思
端口占用查询命令“netstat”详解 Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。 如果你的计算机有时候接收到的数据报导致出错数据或故障,你不必感到奇怪,TCP/IP可以容许这些类型的错误,并能够自动重发数据报。但如果累计的出错情况数目占到所接收的IP数据报相当大的百分比,或者它的数目正迅速增加,那么你就应该使用Netstat查一查为什么会出现这些情况了。 Netstat 详细参数列表 C:\netstat /? 显示协议统计信息和当前 TCP/IP 网络连接。 NETSTAT [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval] -a 显示所有连接和监听端口。 -b 显示包含于创建每个连接或监听端口的可执行组件。在某些情况下已知可执行组件 拥有多个独立组件,并且在这些情况下包含于创建连接或监听端口的组件序列被显示。 这种情况下,可执行组件名在底部的 [] 中,顶部是其调用的组件,等等,直到 TCP/IP 部分。注意此选项可能需要很长时间,如果没有足够权限可能失败。 -e 显示以太网统计信息。此选项可以与 -s 选项组合使用。 -n 以数字形式显示地址和端口号。 -o 显示与每个连接相关的所属进程 ID。 -p proto 显示 proto 指定的协议的连接;proto 可以是 下列协议之一: TCP、UDP、TCPv6 或 UDPv6。 如果与 -s 选项一起使用以显示按协议统计信息,proto 可以是下列协议之一: IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。 -r 显示路由表。 -s 显示按协议统计信息。默认地,显示 IP、 IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息; -p 选项用于指定默认情况的子集。 -v 与 -b 选项一起使用时将显示包含于 为所有可执行组件创建连接或监听端口的 组件。 interval 重新显示选定统计信息,每次显示之间 暂停时间间隔(以秒计)。按 CTRL+C 停止重新 显示统计信息。如果省略,netstat 显示当前 配置信息(只显示一次) (Win2000) C:\netstat /? Displays protocol statistics and current TCP/IP network connections. NETSTAT [-a] [-e] [-n] [-s] [-p proto] [-r] [interval] -a Displays all connections and listening ports. -e Displays Ethernet statistics. This may be combined with the -s option. -n Displays addresses and port numbers in numerical form. -p proto Shows connections for the protocol specified by proto; proto may be TCP or UDP. If used with the -s option to display per-protocol statistics, proto may be TCP, UDP, or IP. -r Displays the routing table. -s Displays per-protocol statistics. By default, statistics are shown for TCP, UDP and IP; the -p option may be used to specify a subset of the default. interval Redisplays selected statistics, pausing interval seconds between each display. Press CTRL+C to stop redisplaying statistics. If omitted, netstat will print the current configuration information once. Netstat的一些常用选项 netstat -s——本选项能够按照各个协议分别显示其统计数据。如果你的应用程序(如Web浏览器)运行速度比较慢,或者不能显示Web页之类的数据,那么你就可以用本选项来查看一下所显示的信息。你需要仔细查看统计数据的各行,找到出错的关键字,进而确定问题所在。 netstat -e——本选项用于显示关于以太网的统计数据。它列出的项目包括传送的数据报的总字节数、错误数、删除数、数据报的数量和广播的数量。这些统计数据既有发送的数据报数量,也有接收的数据报数量。这个选项可以用来统计一些基本的网络流量。 netstat -r——本选项可以显示关于路由表的信息,类似于后面所讲使用route print命令时看到的 信息。除了显示有效路由外,还显示当前有效的连接。 netstat -a——本选项显示一个所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连接请求(LISTENING)的那些连接,断开连接(CLOSE_WAIT)或者处于联机等待状态的(TIME_WAIT)等 netstat -n——显示所有已建立的有效连接。 接下来我们来看一下,微软是怎么说的? 微软公司故意将这个功能强大的命令隐藏起来是因为它对于普通用户来说有些复杂。我们已经知道:Netstat它可以用来获得你的系统网络连接的信息(使用的端口,在使用的协议等 ),收到和发出的数据,被连接的远程系统的端口,Netstat在内存中读取所有的网络信息。 在Internet RFC标准中,Netstat的定义是: Netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。 看其中有个localaddress 和一个foreignaddress如果没打开任何网络连接,却有established说明就有问题,注意,你得保证没有你开的任何的网络连接,包括后台进程,如果还是有established说明才有问题。