`

linux 下端口close_wait 过多

 
阅读更多

情景描述:系统产生大量“Too many open files” 
原因分析:在服务器与客户端通信过程中,因服务器发生了socket未关导致的closed_wait发生,致使监听port打开的句柄数到了1024个,且均处于close_wait的状态,最终造成配置的port被占满出现“Too many open files”,无法再进行通信。 
close_wait状态出现的原因是被动关闭方未关闭socket造成,如附件图所示: 

解决办法:有两种措施可行 
一、解决: 
原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞,所以应该用setSoTimeout()方法设置超时(缺省的设置是0,即超时永远不会发生);超时的判断是累计式的,一次设置后,每次调用引起的阻塞时间都从该值中扣除,直至另一次超时设置或有超时异常抛出。 
比如,某种服务需要三次调用read(),超时设置为1分钟,那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出,如果要在同一个Socket上反复进行这种服务,就要在每次服务之前设置一次超时。 
二、规避: 
调整系统参数,包括句柄相关参数和TCP/IP的参数; 

注意: 
/proc/sys/fs/file-max 是整个系统可以打开的文件数的限制,由sysctl.conf控制; 
ulimit修改的是当前shell和它的子进程可以打开的文件数的限制,由limits.conf控制; 
lsof是列出系统所占用的资源,但是这些资源不一定会占用打开文件号的;比如:共享内存,信号量,消息队列,内存映射等,虽然占用了这些资源,但不占用打开文件号; 
因此,需要调整的是当前用户的子进程打开的文件数的限制,即limits.conf文件的配置; 
如果cat /proc/sys/fs/file-max值为65536或甚至更大,不需要修改该值; 
若ulimit -a ;其open files参数的值小于4096(默认是1024), 则采用如下方法修改open files参数值为8192;方法如下: 
1.使用root登陆,修改文件/etc/security/limits.conf 
vi /etc/security/limits.conf 添加 
xxx - nofile 8192 
xxx 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。 
#<domain>      <type>     <item>         <value> 

*         soft    nofile    8192 
*         hard    nofile    8192 

#所有的用户每个进程可以使用8192个文件描述符。 
2.使这些限制生效 
确定文件/etc/pam.d/login 和/etc/pam.d/sshd包含如下行: 
session required pam_limits.so 
然后用户重新登陆一下即可生效。 
3. 在bash下可以使用ulimit -a 参看是否已经修改: 

一、 修改方法:(暂时生效,重新启动服务器后,会还原成默认值) 
sysctl -w net.ipv4.tcp_keepalive_time=600   
sysctl -w net.ipv4.tcp_keepalive_probes=2 
sysctl -w net.ipv4.tcp_keepalive_intvl=2 

注意:Linux的内核参数调整的是否合理要注意观察,看业务高峰时候效果如何。 

二、 若做如上修改后,可起作用;则做如下修改以便永久生效。 
vi /etc/sysctl.conf 

若配置文件中不存在如下信息,则添加: 
net.ipv4.tcp_keepalive_time = 1800 
net.ipv4.tcp_keepalive_probes = 3 
net.ipv4.tcp_keepalive_intvl = 15 

编辑完 /etc/sysctl.conf,要重启network 才会生效 
/etc/rc.d/init.d/network restart 
然后,执行sysctl命令使修改生效,基本上就算完成了。 

------------------------------------------------------------ 
修改原因: 

当客户端因为某种原因先于服务端发出了FIN信号,就会导致服务端被动关闭,若服务端不主动关闭socket发FIN给Client,此时服务端Socket会处于CLOSE_WAIT状态(而不是LAST_ACK状态)。通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(系统默认超时时间的是7200秒,也就是2小时)。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源,那么通常是等不到释放那一刻,系统就已崩溃。因此,解决这个问题的方法还可以通过修改TCP/IP的参数来缩短这个时间,于是修改tcp_keepalive_*系列参数: 
tcp_keepalive_time: 
/proc/sys/net/ipv4/tcp_keepalive_time 
INTEGER,默认值是7200(2小时) 
当keepalive打开的情况下,TCP发送keepalive消息的频率。建议修改值为1800秒。 

tcp_keepalive_probes:INTEGER 
/proc/sys/net/ipv4/tcp_keepalive_probes 
INTEGER,默认值是9 
TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适) 

tcp_keepalive_intvl:INTEGER 
/proc/sys/net/ipv4/tcp_keepalive_intvl 
INTEGER,默认值为75 
当探测没有确认时,重新发送探测的频度。探测消息发送的频率(在认定连接失效之前,发送多少个TCP的keepalive探测包)。乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒,也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值) 

【检测办法】 
1. 系统不再出现“Too many open files”报错现象。 

2. 处于TIME_WAIT状态的sockets不会激长。 

在 Linux 上可用以下语句看了一下服务器的TCP状态(连接状态数量统计): 

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 

返回结果范例如下: 

ESTABLISHED 1423 
FIN_WAIT1 1 
FIN_WAIT2 262 
SYN_SENT 1 
TIME_WAIT 962

分享到:
评论

相关推荐

    CLOSE_WAIT网络连接无法释放问题解决

    CLOSE_WAIT网络连接无法释放问题解决 CLOSE_WAIT是一个常见的TCP连接状态,指的是服务器端的连接在客户端关闭后还未释放的情况。这种情况经常出现于客户端主动断开连接,但服务器端没有正确关闭连接的情况下。这种...

    linugdjskf_jb51.net_linux_高级编程_源码

    本教程"linugdjskf_jb51.net_linux_高级编程_源码"旨在帮助开发者深入理解Linux环境下的程序设计与实现。 首先,我们要理解Linux的系统调用。系统调用是用户空间程序与操作系统内核交互的主要方式,例如`open()`...

    linux-api-2.6.22.rar_linux_linux api_linux-2.6.22.6

    5. **网络编程**:在Linux 2.6.22.6中,`socket()`函数创建网络套接字,`bind()`将套接字绑定到特定端口,`listen()`和`accept()`处理连接请求,`send()`和`recv()`发送和接收数据。此外,还有`select()`, `poll()`,...

    linux系统调用demo.rar_DEMO_Linux System Calls_linux 编程_linux 系统调用_系

    Linux系统调用是操作系统提供给用户空间程序与内核交互的一种接口,它是实现各种底层功能的基础,如文件操作、进程管理、内存管理、网络通信等。在这个“linux系统调用demo”示例中,我们可以深入理解Linux编程的...

    端口复用

    1. **TCP连接复用**:通过TCP的TIME_WAIT和CLOSE_WAIT状态管理,使得关闭的连接可以尽快被复用。TCP连接四次挥手断开后,端口会进入TIME_WAIT状态,等待一段时间确保没有残留的数据包,然后才能被再次使用。通过缩短...

    Spring Boot假死诊断实战记录

    知识点一: CLOSE_WAIT 状态的端口占用 在文章中,作者遇到一个服务假死的问题,发现了大量的CLOSE_WAIT端口占用。CLOSE_WAIT状态是TCP连接中的一个状态,表示服务器端的连接已经关闭,而客户端还没有关闭连接。这...

    linux网络编程手记.doc

    TCP的状态转移图是理解TCP连接过程的关键,包括SYN_SENT、SYN_RCVD、ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT、CLOSING、LAST_ACK和CLOSED等状态。在连接建立和终止过程中,每个状态都有特定的...

    Linux查看某个端口的连接数的方法

    监控这些状态可以帮助识别可能的网络问题,例如,如果`FIN_WAIT_2`或`CLOSE_WAIT`过多,可能意味着客户端或服务器在关闭连接时出现问题。 总的来说,通过上述方法,我们可以有效地监控Linux系统中特定端口的连接数...

    Linux下TCP/IP服务器实现源码解析(含源码)

    3. **TCP状态机**:TCP连接有多种状态,如CLOSED、LISTEN、SYN_SENT、SYN_RECV、ESTABLISHED、CLOSE_WAIT、LAST_ACK、FIN_WAIT_1、FIN_WAIT_2、CLOSING、TIME_WAIT等。源码分析会揭示这些状态如何转换以及对应的处理...

    Linux下socket设置.pdf

    在Linux环境下,Socket编程是构建网络通信的基本工具。在处理Socket时,往往需要对Socket进行各种设置以优化其性能和适应不同的网络环境。以下是一些关键的Socket设置及其详细解释: 1. **重用地址(SO_REUSEADDR)...

    TCP连接迁移在Linux环境中的实现.pdf

    在Linux中实现TCP连接迁移,首先需要理解TCP连接的状态机,包括SYN_SENT、SYN_RECEIVED、ESTABLISHED、FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT等状态。迁移过程通常在连接已建立(ESTABLISHED)后执行,需要确保迁移...

    linux_programming_code

    5. **网络编程**:Linux提供了丰富的网络编程接口,如`socket()`创建套接字,`bind()`绑定IP和端口,`listen()`监听连接,`accept()`接受连接,`send()`和`recv()`用于数据传输。同时,还有套接字选项和地址解析函数...

    Linux_套接字编程中的_5_个隐患.pdf

    **原因**:在某些情况下,即使先前绑定的套接字已经被关闭,端口仍然不能立即被重用,这是因为TCP套接字可能会进入`TIME_WAIT`状态。在该状态下,端口会被保留一段时间(通常是2至4分钟),直到该状态结束,端口才能...

    Linux_C_函数手册

    《Linux C函数手册》是开发Linux程序的重要参考资料,它涵盖了C语言在Linux环境下的各种函数用法和系统调用,对于程序员来说,是一份不可或缺的工具书。下面将详细介绍手册中的主要内容及其重要性。 首先,手册的...

    Linux下sokcet聊天进程版

    本项目"Linux下socket聊天进程版"就是基于这一技术,实现了父子进程间的交互,为学习和理解Linux socket编程提供了实践案例。下面我们将深入探讨相关的知识点。 首先,我们需要了解什么是Socket。Socket是计算机...

    linux c epoll服务器windows 客户端通信

    总之,Linux C的epoll服务器与Windows Socket客户端通信涉及了网络编程的基本概念,如套接字、端口、I/O事件管理以及跨平台的字节序转换。理解和熟练掌握这些知识点,对构建高效、稳定的分布式系统至关重要。在开发...

    判定断开前的KeepAlive探测次数

    例如,`netstat -a | grep 9877`用于查找端口9877的所有连接状态,显示结果中的`CLOSE_WAIT`状态表明连接正在等待关闭,但客户端尚未完全断开连接。 针对`CLOSE_WAIT`状态的处理,通常需要关注程序的正确关闭逻辑,...

Global site tag (gtag.js) - Google Analytics