Linux TIME_WAIT 太多 优化 解决

本文介绍了在CentOS 7系统中遇到的大量TIME_WAIT状态导致MySQL卡死的问题,以及如何通过修改内核参数、扩展文件描述符数量等进行优化。内容包括修改系统配置文件、调整TCP/IP相关参数,以改善高并发环境下的服务器性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

MySQL经常卡死,netstat -nat看一下,TIME_WAIT成千上万……

解决

修改/etc/sysctl.conf文件,增加以下内容

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

保存完后使用sysctl -p使系统生效。

分析[转载]

客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口状态为TIME_WAIT.主动关闭的一方在发送最后一个 ack 后,就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间,这个是TCP/IP必不可少的,也就是“解决”不了的,也就是TCP/IP设计者本来是这么设计的。

 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,表示关闭

net.ipv4.tcp_fin_timeout = 30
//修改系統默认的 TIMEOUT 时间

CentOS 7

在centos7 之间,我们修改内核参数,都是使用/etc/sysctl.conf文件,但是在7之后,就不再是这个文件了

看看

[root@test74 ~]# cat /etc/sysctl.conf

 sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
[root@test74 ~]#

所以如果我们想修改内核参数,就修改这个文 /usr/lib/sysctl.d/00-system.conf

#关闭ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

# 避免放大攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1

# 开启恶意icmp错误消息保护
net.ipv4.icmp_ignore_bogus_error_responses = 1

#关闭路由转发
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

#开启反向路径过滤
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

#处理无源路由的包
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

#关闭sysrq功能
kernel.sysrq = 0

#core文件名中添加pid作为扩展名
kernel.core_uses_pid = 1

# 开启SYN洪水攻击保护
net.ipv4.tcp_syncookies = 1

#修改消息队列长度
kernel.msgmnb = 65536
kernel.msgmax = 65536

#设置最大内存共享段大小bytes
kernel.shmmax = 68719476736
kernel.shmall = 4294967296

#timewait的数量,默认180000
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

出处:http://yiyulinfeng.com/2018/01/22/centos-7-%E5%86%85%E6%A0%B8%E6%96%87%E4%BB%B6system-conf/

CentOS7 高并发优化

扩展最大文件描述符数量

ulimit -SHn 1024000
echo “ulimit -SHn 1024000” >> /etc/rc.d/rc.local
source /etc/rc.d/rc.local

内核参数优化 /etc/sysctl.conf

vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time=120
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.all.arp_announce=2
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_max_tw_buckets = 100
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_syn_backlog = 3240000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_no_metrics_save=1
#net.ipv4.tcp_keepalive_time = 60
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv4.conf.lo.arp_announce=2
fs.file-max = 40000500
fs.nr_open = 40000500
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_keepalive_time = 1
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_mem = 768432 2097152 15242880
net.ipv4.tcp_rmem = 4096 4096 33554432
net.ipv4.tcp_wmem = 4096 4096 33554432
net.core.somaxconn = 6553600
net.ipv4.ip_local_port_range = 2048 64500
net.core.wmem_default = 183888608
net.core.rmem_default = 183888608
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.core.netdev_max_backlog = 2621244
kernel.sem=250 65536 100 2048
kernel.shmmni = 655360
kernel.shmmax = 34359738368
kerntl.shmall = 4194304
kernel.msgmni = 65535
kernel.msgmax = 65536
kernel.msgmnb = 65536
net.netfilter.nf_conntrack_max=1000000
net.nf_conntrack_max=1000000
net.ipv4.netfilter.ip_conntrack_max=1000000
kernel.perf_cpu_time_max_percent=60
kernel.perf_event_max_sample_rate=6250
net.ipv4.tcp_max_orphans=1048576
kernel.sched_migration_cost_ns=5000000
net.core.optmem_max = 25165824
vm.max_map_count=262144
kernel.sem=10000 2560000 10000 256

最后sysctl -p
以上摘自https://www.jianshu.com/p/d05fae1f1724

Linux服务器下查看网络连接的状态

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

它会显示例如下面的信息:

LISTEN 18
TIME_WAIT 21814
ESTABLISHED 135

其他参考

  1. CentOS 7 运维优化 - 宁静致远’s 博客 - CSDN博客
  2. centos7之系统优化方案 - Jokerbj - 博客园
  3. centos7.2系统优化 - fangoooooooooooo的博客 - CSDN博客
<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、付费专栏及课程。

余额充值