I have written a small program that interacts with a server on a specific port. The program works fine, but:
我编写了一个与特定端口上的服务器交互的小程序。这个程序运行得很好,但是:
Once the program terminated unexpectedly, and ever since that socket connection is shown in CLOSE_WAIT
state. If I try to run a program it hangs and I have to force it close, which accumulates even more CLOSE_WAIT
socket connections.
一旦程序意外终止,并且从此套接字连接显示在CLOSE_WAIT状态。如果我尝试运行一个程序,它就挂起了,我必须将它关闭,这就会积累更多的CLOSE_WAIT套接字连接。
Is there a way to flush these connections?
有办法清除这些联系吗?
4 个解决方案
#1
53
CLOSE_WAIT
means your program is still running, and hasn't closed the socket (and the kernel is waiting for it to do so). Add -p
to netstat
to get the pid, and then kill it more forcefully (with SIGKILL
if needed). That should get rid of your CLOSE_WAIT
sockets. You can also use ps
to find the pid.
CLOSE_WAIT表示程序仍然在运行,并且没有关闭套接字(内核正在等待它这样做)。在netstat中添加-p,以获得pid,然后更有力地杀死它(如果需要,使用SIGKILL)。这应该可以去掉CLOSE_WAIT套接字。您还可以使用ps查找pid。
SO_REUSEADDR
is for servers and TIME_WAIT
sockets, so doesn't apply here.
SO_REUSEADDR是用于服务器和TIME_WAIT套接字的,所以这里不适用。
#2
27
As described by Crist Clark.
正如克里斯特·克拉克所描述的。
CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.
CLOSE_WAIT意味着连接的本地端从另一端接收了一个FIN,但是操作系统在本地端等待程序来关闭它的连接。
The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.
问题是在本地机器上运行的程序没有关闭套接字。这不是TCP调优问题。当程序保持连接打开时,连接可以(非常正确地)永远保持在CLOSE_WAIT中。
Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state).
一旦本地程序关闭套接字,操作系统可以发送远程终端转换你的鳍LAST_ACK当你等待ACK的鳍。一旦收到,连接完成后,滴从连接表(如果你的结束是在CLOSE_WAIT你不最终TIME_WAIT状态)。
#3
5
I'm also having the same issue with a very latest Tomcat server (7.0.40). It goes non-responsive once for a couple of days.
我对最新的Tomcat服务器(7.0.40)也有同样的问题。它会有几天没有反应。
To see open connections, you may use:
要查看打开的连接,您可以使用:
sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT
As mentioned in this post, you may use /proc/sys/net/ipv4/tcp_keepalive_time
to view the values. The value seems to be in seconds and defaults to 7200 (i.e. 2 hours).
如本文所述,您可以使用/proc/sys/net/ipv4/tcp_keepalive_time来查看这些值。值似乎是秒,默认值是7200(即2小时)。
To change them, you need to edit /etc/sysctl.conf
.
要更改它们,需要编辑/etc/sysctl.conf。
Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`
#4
4
Even though too much of CLOSE_WAIT connections means there is something wrong with your code in the first and this is accepted not good practice.
尽管太多的CLOSE_WAIT连接意味着您的代码在第一次出现了问题,但这并不是一个好的实践。
You might want to check out: https://github.com/rghose/kill-close-wait-connections
您可能需要检查:https://github.com/rghose/kill-wait -connections
What this script does is send out the ACK which the connection was waiting for.
这个脚本所做的就是发送连接正在等待的ACK。
This is what worked for me.
这对我起了作用。
#1
53
CLOSE_WAIT
means your program is still running, and hasn't closed the socket (and the kernel is waiting for it to do so). Add -p
to netstat
to get the pid, and then kill it more forcefully (with SIGKILL
if needed). That should get rid of your CLOSE_WAIT
sockets. You can also use ps
to find the pid.
CLOSE_WAIT表示程序仍然在运行,并且没有关闭套接字(内核正在等待它这样做)。在netstat中添加-p,以获得pid,然后更有力地杀死它(如果需要,使用SIGKILL)。这应该可以去掉CLOSE_WAIT套接字。您还可以使用ps查找pid。
SO_REUSEADDR
is for servers and TIME_WAIT
sockets, so doesn't apply here.
SO_REUSEADDR是用于服务器和TIME_WAIT套接字的,所以这里不适用。
#2
27
As described by Crist Clark.
正如克里斯特·克拉克所描述的。
CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.
CLOSE_WAIT意味着连接的本地端从另一端接收了一个FIN,但是操作系统在本地端等待程序来关闭它的连接。
The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.
问题是在本地机器上运行的程序没有关闭套接字。这不是TCP调优问题。当程序保持连接打开时,连接可以(非常正确地)永远保持在CLOSE_WAIT中。
Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state).
一旦本地程序关闭套接字,操作系统可以发送远程终端转换你的鳍LAST_ACK当你等待ACK的鳍。一旦收到,连接完成后,滴从连接表(如果你的结束是在CLOSE_WAIT你不最终TIME_WAIT状态)。
#3
5
I'm also having the same issue with a very latest Tomcat server (7.0.40). It goes non-responsive once for a couple of days.
我对最新的Tomcat服务器(7.0.40)也有同样的问题。它会有几天没有反应。
To see open connections, you may use:
要查看打开的连接,您可以使用:
sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT
As mentioned in this post, you may use /proc/sys/net/ipv4/tcp_keepalive_time
to view the values. The value seems to be in seconds and defaults to 7200 (i.e. 2 hours).
如本文所述,您可以使用/proc/sys/net/ipv4/tcp_keepalive_time来查看这些值。值似乎是秒,默认值是7200(即2小时)。
To change them, you need to edit /etc/sysctl.conf
.
要更改它们,需要编辑/etc/sysctl.conf。
Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`
#4
4
Even though too much of CLOSE_WAIT connections means there is something wrong with your code in the first and this is accepted not good practice.
尽管太多的CLOSE_WAIT连接意味着您的代码在第一次出现了问题,但这并不是一个好的实践。
You might want to check out: https://github.com/rghose/kill-close-wait-connections
您可能需要检查:https://github.com/rghose/kill-wait -connections
What this script does is send out the ACK which the connection was waiting for.
这个脚本所做的就是发送连接正在等待的ACK。
This is what worked for me.
这对我起了作用。