优化服务器以减少 TIME_WAIT

本文主要参考链接 :https://www.jianshu.com/p/6eaac07c93ed

其它链接 :https://www.oschina.net/translate/optimising-nginx-node-js-and-networking-for-heavy-workloads?print

背景

1. nginx 代理 nodejs, 但都在同一台服务器上

2. nodejs 的端口是3000

现象

1.  服务器端 出现大量TIME_WAIT

     查询方式     

1)ss查看比netstat要快:
ss -s #查看TW的数量
2)netstat方法:
shell> netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

2. 造成的问题

   服务器存在大量TIME_WAIT链接,导致无法为新的请求分配链接 

3. 参考解决方案 

参考 :Nginx做前端Proxy时TIME_WAIT过多的问题 http://www.cnblogs.com/QLeelulu/p/3601499.html
要点

  • 修改系统预留端口,防止自己进程监听的大于1024的端口被占用
  • 解决TW过多:修改nginx upstream配置中的keepalive时长并且在server段中使用http1.1(1.0不支持keepalive)

upstream http_backend {
    server 127.0.0.1:8080;

     keepalive 16;
     #此参数表示上每个worker进程保持空闲连接的最大数量,这个数量不能太大以致无法分配其它链接
     #也不能太小,以致于没有足够的可重用的连接,导致开辟大量的短连接,最后仍是很多TIME_WAIT
     #nginx总的keepalive连接池大小 = keepalive 取值 * nginx worker数
     #可参考官方文档 :http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
}

server {
...

location /http/ {
   proxy_pass http://http_backend;
   proxy_http_version 1.1;               #使用http1.1
   proxy_set_header Connection ""; # 置空头信息中的connection,否则有可能会是 closed
...
}
}

linux相关内核参数优化 参考:
https://huoding.com/2013/12/31/316
要点

  • ip_conntrack:顾名思义就是跟踪连接。(引入问题过多不建议使用)
  • tcp_tw_recycle:顾名思义就是回收TIME_WAIT连接。(NAT模式下有问题,产生时间戳混乱,不建议使用)
  • tcp_tw_reuse:顾名思义就是复用TIME_WAIT连接。(作为连接的发起方(Client)有用(需网络稳定),作为被连接方基本没用)
  • tcp_max_tw_buckets:顾名思义就是控制TIME_WAIT总数。(治标不治本,限制tw队列大小系统日志会报「TCP: time wait bucket table overflow」)

有时候,如果我们换个角度去看问题,往往能得到四两拨千斤的效果。前面提到的例子:客户端向服务端发起HTTP请求,服务端响应后主动关闭连接,于是TIME_WAIT便留在了服务端。这里的关键在于主动关闭连接的是服务端!在关闭TCP连接的时候,先出手的一方注定逃不开TIME_WAIT的宿命,套用一句歌词:把我的悲伤留给自己,你的美丽让你带走。如果客户端可控的话,那么在服务端打开KeepAlive,尽可能不让服务端主动关闭连接,而让客户端主动关闭连接,如此一来问题便迎刃而解了。

参数配置示例: (参考 :https://www.oschina.net/translate/optimising-nginx-node-js-and-networking-for-heavy-workloads?print
(为高负载网络优化 Nginx 和 Node.js ))

net.ipv4.ip_local_port_range='1024 65000'
net.ipv4.ip_local_reserved_ports = 你要保留的端口如(3000,27017-27018)
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog='4096'
net.core.rmem_max='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480'
net.ipv4.tcp_max_tw_buckets='400000'
net.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_syn_retries='2'
net.ipv4.tcp_synack_retries='2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'

还有另一个示例:(来自https://blog.csdn.net/shootyou/article/details/6622226

#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间 
net.ipv4.tcp_syn_retries=2
#net.ipv4.tcp_synack_retries=2
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
net.ipv4.tcp_keepalive_time=1200
net.ipv4.tcp_orphan_retries=3
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
net.ipv4.tcp_fin_timeout=30  
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 4096
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1

#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 1

##减少超时前的探测次数 
net.ipv4.tcp_keepalive_probes=5 
##优化网络设备接收队列 
net.core.netdev_max_backlog=3000 

 

重点说明其中几个重要的。

net.ipv4.ip_local_port_range

为了替上游的应用服务下游的客户端,NginX必须打开两条TCP连接,一条连接客户端,一条连接应用。在服务器收到很多连接时,系统的可用端口将很快被耗尽。通过修改net.ipv4.ip_local_port_range参数,可以将可用端口的范围改大。如果在/var/log/syslog中发现有这样的错误: “possible SYN flooding on port 80. Sending cookies”,即表明系统找不到可用端口。增大net.ipv4.ip_local_port_range参数可以减少这个错误。 但要注意保留正常的服务端口(net.ipv4.ip_local_reserved_ports)
这个参数的默认设置可通过下面的命令查看(也可以在这里修改):

cat /proc/sys/net/ipv4/ip_local_port_range
32768   609995

net.ipv4.ip_local_reserved_ports

因为net.ipv4.ip_local_port_range扩大的范围,所以有可能造成正常服务在重启过程中,端口在服务器分配随机端口时被占用,导致不能正常重启。 所以可以通过这个参数来指定需要保留的端口。
参考:http://www.ttlsa.com/linux/reserved-port-to-avoid-occupying-ip_local_reserved_ports/ 

net.ipv4.tcp_tw_reuse

当服务器需要在大量TCP连接之间切换时,会产生大量处于TIME_WAIT状态的连接。TIME_WAIT意味着连接本身是关闭的,但资源还没有释放。将net_ipv4_tcp_tw_reuse设置为1是让内核在安全时尽量回收连接,这比重新建立新连接要便宜得多。

net.ipv4.tcp_fin_timeout

这是处于TIME_WAIT状态的连接在回收前必须等待的最小时间。改小它可以加快回收。

 

 

4.  需要注意的地方

    因为我的情况是 nginx 和 node 在一台机器上,要么nginx保留很多TIME_WAIT,要么NODE保留很多TIME_WAIT ,所以让客户端主动关闭连接的方式对于这种情况不能走到什么效果,重点是要提高重用链接数量。

    nginx总的keepalive连接池大小 = keepalive 取值 * nginx worker数    

5. 其它案例分析

参考 :https://blog.csdn.net/liuxiao723846/article/details/50747366

案例一:

将nginx作为反向代理时,后连tomcat等服务器。测试中不同并发压力下多次、反复出现nginx服务器端口资源耗尽的问题。表现为nginx服务器出现大量time_wait状态连接,端口资源耗尽(nginx报错:cannot assign requested address )。首先检查nginx开启了长连接keepalive,但是系统仍然出现了大量的TIME_WAIT,这就和之前提到的当系统产生TIME_WAIT的速度大于其消耗速度时,就会累计TIME_WAIT。原因是:keepalive取配置太小,将其增大后问题得以解决。(PS:nginx总的keepalive连接池大小 = keepalive取值 * nginx worker数)

案例二:

某应用其中一层系统架构Nginx+Tomcat,tomcat服务器上出现了大量的TIME_WAIT。

Nginx作为反向代理,长连接配置主要有三项,upstream中的keepalive设置单个worker最大请求数,参数proxy_http_version  1.1强制转换为http1.1协议(默认支持长连接),proxy_set_header Connection将请求头部connection为空(http1.0请求默认connection头部为close),后两项要放到server域中,配置后问题即可解决。

但是我们不禁会尝试疑问TIME_WAIT出现在Tomcat而不是在Nginx上?从抓包可以看出Nginx发送给Tomcat包头部Connection为close,所以Tomcat在处理完head请求后就主动关闭,所以TIME_WAIT出现在Tomcat服务器。 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器出现大量time_wait是指在TCP连接断开后,服务器端口仍处于等待状态的情况。这可能会导致服务器资源的浪费,影响服务器的性能和可用性。以下是理解并解决这个问题的步骤: 首先,需要理解time_wait的原因:TCP连接的断开是一个多步骤的过程,在最后一个ACK报文发送后,服务器端口会进入time_wait状态一段时间,以确保在这段时间内没有延迟的报文重新出现。这是网络协议设计的一部分,用于确保数据传输的可靠性。 为了解决服务器出现大量time_wait的问题,可以采取以下措施: 1. 调整服务器参数:可以通过修改服务器操作系统的参数来调整time_wait状态的时间。例如,可以减少time_wait状态的持续时间,以释放服务器资源。具体的操作方法可以参考操作系统的文档或相关文档。 2. 加大服务器资源:如果服务器出现大量time_wait的问题,可能是服务器的资源(例如端口号)不足造成的。此时,可以考虑增加服务器的资源,例如扩大服务器的端口范围等。 3. 优化应用程序代码:服务器出现大量time_wait可能是应用程序代码设计不佳造成的。在应用程序中,可以优化代码,以减少TCP连接的数量和时间。例如,可以使用连接池来重用连接,或者调整连接关闭的时机。 4. 负载均衡和故障转移:如果服务器经常出现大量time_wait,可能是由于服务器负载过高或单点故障引起的。此时,可以考虑使用负载均衡和故障转移技术来分散流量和提高服务器的可用性,从而减少time_wait的数量。 总之,彻底理解并解决服务器出现大量time_wait的问题需要对网络协议、服务器参数和应用程序代码等方面有一定的了解。通过调整参数、加大服务器资源、优化代码以及使用负载均衡和故障转移等技术,可以有效地减少time_wait的数量,提高服务器的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值