linux 下解决apache TIME_WAIT连接过多

减少TIME_WAIT连接
本文介绍了解决Apache服务器中大量TIME_WAIT连接的方法,通过调整Linux内核参数如tcp_tw_reuse和tcp_tw_recycle,有效减少了TIME_WAIT状态的连接数量。
经常检查apache的连接数,会发现很多无用的time_wait连接。有人说这是正常的,是因为一个请求中途中断造成的;还有人说微软的IE连接时产生的Time_wait会比用Firefox连接时多。个人认为有一定的Time_wait是正常的,如果超过了连接数的比例就不是很正常,所以还是找来方法解决一下。 

  先检查一下time wait的值: 

  [root@aaa1 ~]#sysctl -a | grep time | grep wait 

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120 

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60 

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120 

  这里解决问题的关键是如何能够重复利用time_wait的值,检查net.ipv4.tcp_tw当前值: 

  [root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw 

  net.ipv4.tcp_tw_reuse = 0 

  net.ipv4.tcp_tw_recycle = 0 

  增加或修改net.ipv4.tcp_tw值,将当前的值更改为1分钟(reuse是表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接; recycle是加速TIME-WAIT sockets回收): 

  [root@aaa1 ~]# vi /etc/sysctl.conf 

  net.ipv4.tcp_tw_reuse = 1 

  net.ipv4.tcp_tw_recycle = 1 

  使内核参数生效: 

  [root@aaa1 ~]# sysctl -p 

  用netstat再观察时会发现已经恢复正常。 

  结合DDOS和TIME_WAIT过多,建议增加如下参数设置: 

  # Use TCP syncookies when needed 

  net.ipv4.tcp_syncookies = 1 

  net.ipv4.tcp_synack_retries=3 

  net.ipv4.tcp_syn_retries=3 

  net.ipv4.tcp_max_syn_backlog=2048 

  # Enable TCP window scaling 

  net.ipv4.tcp_window_scaling: = 1 

  # Increase TCP max buffer size 

  net.core.rmem_max = 16777216 

  net.core.wmem_max = 16777216 

  # Increase Linux autotuning TCP buffer limits 

  net.ipv4.tcp_rmem = 4096 87380 16777216 

  net.ipv4.tcp_wmem = 4096 65536 16777216 

  # Increase number of ports available 

  net.ipv4.tcp_fin_timeout = 30 

  net.ipv4.tcp_keepalive_time = 300 

  net.ipv4.tcp_tw_reuse = 1 

  net.ipv4.tcp_tw_recycle = 1 

  net.ipv4.ip_local_port_range = 5000 65000 

  附:查看当前的连接数状况 

  netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n 

  1 established 

  1 State 

  2 LAST_ACK 

  4 CLOSING 

  4 FIN_WAIT2 

  9 LISTEN 

  17 FIN_WAIT1 

  18 SYN_RECV 

  27 ESTABLISHED 

  811 TIME_WAIT 

  上面的命令可以帮助分析哪种tcp状态数量异常。其中的SYN_RECV表示正在等待处理的请求数;ESTABLISHED表示正常数据传输状态;TIME_WAIT表示处理完毕,等待超时结束的请求数。 

  附:查看IP连接数状况 

  netstat -nat|grep ":80"|awk '{print $5}' |awk -F: '{print $1}' | sort| uniq -c|sort -n 

  发现异常的,可以封了这个IP 

 新增的一组Apache服务器上线以来,我用netstat -an命令发现服务器中有大量状态为TIME-WAIT的TCP连接,于是用/sbin/sysctl -a查看了一下Linux的各项内核参数,并翻阅有关资料,决定修改其中的两项参数,以达到减少TCP连接中TIME-WAIT sockets的目的。 
  vi /etc/sysctl.conf 
  编辑/etc/sysctl.conf文件,增加三行: 
  引用 
  net.ipv4.tcp_syncookies = 1 
  net.ipv4.tcp_tw_reuse = 1 
  net.ipv4.tcp_tw_recycle = 1 
  说明: 
  net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; 
  net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; 
  net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 
  再执行以下命令,让修改结果立即生效: 
  /sbin/sysctl -p 
  用以下语句看了一下服务器的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 
  效果:处于TIME_WAIT状态的sockets从原来的10000多减少到1000左右。处于SYN_RECV等待处理状态的sockets为0,原来的为50~300。(王朝网络 wangchao.net.cn) 
<think>好的,我现在需要解决用户提到的Linux系统中TIME_WAIT状态过多导致Java程序出现NoRouteToHostException的问题。首先,我应该回忆一下相关的网络知识,特别是关于TCP连接的状态转换。TIME_WAIT状态出现在主动关闭连接的一方,也就是当TCP连接正常关闭时,会进入这个状态,持续2MSL(Maximum Segment Lifetime)时间,通常是60秒。这是为了确保最后一个ACK报文能够到达对方,并处理可能延迟到达的数据包,防止旧连接的数据干扰新连接。 用户的问题是由于系统中存在大量的TIME_WAIT连接,导致本地端口被耗尽,无法分配新的端口,从而引发NoRouteToHostException。这时候,Java应用程序在尝试建立新的Socket连接时,无法获取可用的本地端口,因此报错。 接下来,我需要考虑如何减少TIME_WAIT的数量或者优化端口的使用。根据引用中的资料,特别是引用[3]提到的修改本地端口范围,可能需要调整sysctl.conf中的参数。此外,可能还需要调整其他相关的内核参数,比如开启端口重用,或者调整TIME_WAIT的超时时间。 首先,调整本地端口范围。默认的端口范围可能较小,导致在高并发下快速耗尽。将net.ipv4.ip_local_port_range设置为更大的范围,如10000到65000,这样可以提供更多的可用端口,延缓耗尽的时间。 其次,开启端口重用(SO_REUSEADDR和SO_REUSEPORT),允许新的连接重用处于TIME_WAIT状态的端口。这可以通过设置net.ipv4.tcp_tw_reuse为1来实现。需要注意的是,这个参数需要和tcp_timestamps一起启用,确保时间戳的支持,以避免安全问题。 另外,调整TIME_WAIT的超时时间也是一个可能的解决方案,但不太推荐,因为这可能影响TCP的可靠性。不过,如果有必要,可以设置net.ipv4.tcp_fin_timeout为一个较小的值,但这通常不如调整端口重用有效。 还有,增加最大文件描述符数也可能有帮助,特别是在高并发场景下,确保系统可以处理更多的连接。这需要调整ulimit或相关的文件描述符限制。 然后,需要考虑Java程序本身的优化,比如使用连接池来复用连接,减少频繁创建和关闭连接的情况。同时,检查代码中是否存在未正确关闭连接的情况,确保每次连接使用后都被正确释放。 此外,可能还需要调整TCP的keepalive参数,减少不必要的连接保持时间,从而更快地释放资源。不过,这可能影响长连接的场景,需要根据具体情况权衡。 最后,实施这些修改后,需要通过sysctl -p命令使配置生效,并重启受影响的Java应用。之后,监控系统的网络状态,使用netstat或ss命令查看TIME_WAIT的数量是否减少,以及应用程序是否恢复正常。 需要验证每个步骤的正确性,比如确认内核参数的作用,避免设置错误导致其他问题。例如,调整tcp_max_tw_buckets可以限制TIME_WAIT的数量,但设置过低可能导致连接过早被关闭。因此,需要根据实际负载和系统资源进行合理配置。 总结来说,解决方案应围绕调整内核参数、优化端口使用、改进应用程序的连接管理三个方面展开。同时,引用中提到的修改本地端口范围和启用端口重用是关键步骤,结合其他优化措施,可以有效缓解问题。</think>### 解决方案:Linux系统中TIME_WAIT过多导致`NoRouteToHostException`的解决方法 当Linux系统中存在大量`TIME_WAIT`状态的TCP连接时,会导致本地端口耗尽,Java程序无法分配新端口,从而抛出`java.net.NoRouteToHostException`。以下是逐步解决方案: --- #### **1. 调整本地端口范围** 通过扩大可用本地端口范围,延缓端口耗尽的速度: ```bash # 编辑系统参数配置文件 sudo vi /etc/sysctl.conf # 添加或修改以下参数(10000~65000为端口范围) net.ipv4.ip_local_port_range = 10000 65000 # 保存后生效配置 sudo sysctl -p ``` 此修改允许系统使用更多端口,减少因端口不足导致的错误[^3]。 --- #### **2. 启用端口快速重用** 允许内核重用处于`TIME_WAIT`状态的端口(需确保时间戳功能开启): ```bash sudo vi /etc/sysctl.conf # 添加以下参数 net.ipv4.tcp_tw_reuse = 1 # 允许重用TIME_WAIT端口 net.ipv4.tcp_timestamps = 1 # 启用时间戳支持 # 生效配置 sudo sysctl -p ``` 此配置可减少`TIME_WAIT`状态的持续时间。 --- #### **3. 调整TIME_WAIT相关参数** 限制系统中`TIME_WAIT`连接的最大数量: ```bash sudo vi /etc/sysctl.conf # 添加以下参数 net.ipv4.tcp_max_tw_buckets = 200000 # 增加TIME_WAIT连接的最大桶数 # 生效配置 sudo sysctl -p ``` --- #### **4. 优化应用程序行为** - **使用连接池**:在Java代码中使用连接池(如Apache HttpClient、HikariCP等),避免频繁创建/关闭短连接。 - **关闭连接时使用`Connection: close`**:确保HTTP请求头中明确关闭连接,避免长连接积累。 - **检查代码泄漏**:确保所有Socket或HTTP连接正确调用`close()`方法。 --- #### **5. 监控与验证** - **查看当前TIME_WAIT数量**: ```bash ss -s | grep TIME-WAIT ``` - **检查端口使用情况**: ```bash netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c ``` --- #### **6. 其他可选优化** - **减少`FIN_WAIT2`时间**(默认60秒): ```bash net.ipv4.tcp_fin_timeout = 30 ``` - **增加文件描述符限制**: ```bash # 修改/etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 ``` --- ### 总结 通过调整内核参数(如端口范围、TIME_WAIT重用)和优化应用程序设计(如连接池),可有效缓解因`TIME_WAIT`过多导致的`NoRouteToHostException`问题。建议优先使用参数`net.ipv4.tcp_tw_reuse`和`net.ipv4.ip_local_port_range`,并结合代码级优化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值