全部都是TIME_WAIT的原因!
学业任务
如果突然说会有高流量的促销活动之类的到来,虽然会遇到一些困难,但现在是云时代,只要提升一下硬件配置应该就能解决。所以我先加大了CPU和内存,但是一旦活动开始,却意外地很快就无法从浏览器连接上!
CPU和内存负载都并不是特别高。当我查看了一下发现有大量的TIME_WAIT。
暂时想办法解决
请通过命令确认TIME_WAIT的数目
$ netstat -anp | grep 时间等待
__(snip)__
tcp 0 0 192.168.1.1:80 192.97.67.192:56305 TIME_WAIT -
tcp 0 0 192.168.1.1:80 192.63.64.145:65274 TIME_WAIT -
tcp 0 0 192.168.1.1:80 192.39.2.205:3325 TIME_WAIT -
tcp 0 0 192.168.1.1:80 192.102.102.9:54300 TIME_WAIT -
tcp 0 0 192.168.1.1:80 192.71.125.102:61769 TIME_WAIT -
__(snip)__
更改内核参数设置
根据 IBM 的 Red Hat Enterprise Linux 调整指南,通过对 tcp_tw_reuse、tcp_tw_recycle 和 tcp_fin_timeout 参数进行以下附加设置,可以降低这些值。
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
设置内核参数的应用
将以下命令进行中文表述:
# sysctl -p
运行 sysctl 命令并应用配置。
嗯,确实可看到TIME_WAIT数量在减少。
TIME_WAIT是什么意思?
让我们来查看RFC793中原始TCP标准和TCP Reno的拥塞控制机制的网络状态转移图。
嗯,看起来这个通信状态从FIN-WAIT-1/FIN-WAIT-2/CLOSING转变过来,似乎没有必要停留。
换个角度看
维基百科:从传输控制协议的ESTABLISHED状态到CLOSED状态的状态转移进行顺序观察。
比如,如果Initiator是Web服务器,而Receiver是电脑或手机,那么当Web服务器处于TIME_WAIT状态时,它是不是在等待手机关闭呢。
如果是这样的话,如果Receiver的CLOSED操作尽早完成,那么Initiator方面的等待时间(tw_fin_timeout值)是不是可以尽量缩短?
再次查看内核参数的内容
TCP连接终止超时时间
如果由我们这一方关闭,则将套接字保持为FIN-WAIT-2状态的时间。对等方可能会断开连接,并且不会关闭自己的一方,甚至可能意外死机。默认值为60秒。2.2版本中使用的通常值为180秒,您可以恢复它,但要记住,如果您的机器是负载较轻的WEB服务器,您有可能因为大量的已断开连接的套接字而导致内存溢出,FIN-WAIT-2套接字比FIN-WAIT-1套接字危险性较低,因为它们最多占用1.5K的内存,但是它们往往存在时间更长。
-
- ソケットをこちら(上記Receiver)側からクローズしたときに、FIN-WAIT-2 状態に保つ時間。
-
- 通信先が切れてしまったり、先方でのクローズをずっと行わなかったり、 あるいは予期しない形で終了してしまうかもしれません。
-
- デフォルトの値は 60 秒です。
-
- 2.2 で用いられていた通常の値は 180 秒で、 この設定にすることもできますが、マシンが (必ずしも負荷が高くなくても) WEB サーバだったりすると、 膨大な FIN-WAIT-2 ソケットのせいでメモリが溢れる危険もあります。
- FIN-WAIT-2 ソケットは 1.5K のメモリしか消費しないので FIN-WAIT-1 ほど危険ではありませんが、長く存在する傾向があります。
TCP_TW_REUSE 是 TCP 协议的一个选项。
当从协议的角度来看是安全的时候,这允许在TIME_WAIT状态下重用套接字以用于新连接。默认值为0(禁用)。这通常是tcp_tw_recycle的更安全的选择。
注意:tcp_tw_reuse设置在存在大量短连接并处于TIME_WAIT状态的环境中特别有用,比如Web服务器和负载均衡器。重用套接字可以非常有效地减少服务器负载。从Linux 2.6.7开始(并反向兼容到2.4.27),Linux还提供了传统的“reno”算法以外的替代拥塞控制算法。这些算法旨在快速恢复高速广域网上的数据包丢失。
-
- これは、プロトコルの観点から安全に新しい接続でTIME_WAITのソケット再利用することを許可します。
-
- デフォルトは0(無効)。
- これは一般的にtcp_tw_recycleよりも安全な方法です。
注意:tcp_tw_reuse设置在像Web服务器或负载均衡器这样的环境中特别有用,这些环境中会有大量的短连接处于TIME_WAIT状态。重复使用套接字对于减轻服务器负载非常有效。从Linux2.6.7开始,Linux实现了替代的拥塞控制算法,除了传统的“Reno”算法。这些算法旨在快速恢复从高速广域网上的数据包丢失。
TCP_TW_RECYCLE 可以被翻译为 “TCP 超时连接”]
这使得TIME_WAIT套接字能够快速回收。默认值为0(禁用)。在负载均衡器上使用时应该谨慎。
-
- TIME-WAITソケットを早く再利用することが出来る。
-
- デフォルトの値は0。
-
- ロードバランサなどを使用している場合は注意して使用する必要がある。
[注]kernel4.1.2で削除されているようです。 tcp: remove tcp_tw_recycle
TCP_FIN_TIMEOUT应该设置为多久合适?
我尝试了一些网站(1,2,3),虽然找到了很多关于30秒的说法,但范围从1到30秒,没有什么明显的决定性因素。由于网络速度有所提升,60秒可能太长了,但可以根据各个服务器环境进行调整。
自行思考并确定设定的参考值
-
- なるべく積極的にリソースを開放したい
-
- 外部と通信するものは通信状態が様々なのである程度時間を保つ
- 内部で通信するものはGigabit Ethernetなどが増えているのである程度短くできる
Hadoop15〜30秒
KVS(cassandra)1〜5秒攻めすぎ?
要确认TIME_WAIT的等待时间状态,该怎么做?
Netstat还有一些有用的选项。使用这些选项可以在进行调整的同时进行确认,这是一个好主意。
netstat -anpto 的中文表述:展示网络连接状态,包括监听和已建立的连接,并显示相关进程信息。
__(snip)__
tcp 0 0 192.168.1.1:80 192.2.197.186:58601 TIME_WAIT - timewait (52.22/0/0)
tcp 0 0 192.168.1.1:80 192.82.117.34:56977 TIME_WAIT - timewait (30.70/0/0)
tcp 0 0 192.168.1.1:80 192.135.233.60:60358 TIME_WAIT - timewait (40.65/0/0)
tcp 0 0 192.168.1.1:80 192.4.206.121:64294 TIME_WAIT - timewait (29.46/0/0)
tcp 0 0 192.168.1.1:80 192.2.197.186:58600 TIME_WAIT - timewait (52.22/0/0)
tcp 0 0 192.168.1.1:80 192.82.117.34:56464 TIME_WAIT - timewait (28.03/0/0)
tcp 0 0 192.168.1.1:80 192.169.145.26:60343 TIME_WAIT - timewait (13.64/0/0)
tcp 0 0 192.168.1.1:80 192.193.81.104:61038 TIME_WAIT - timewait (24.37/0/0)
__(snip)__
“tcp_tw_recycle 存在什么问题吗?”
根据对Koko和Koko2的验证,使用net.ipv4.tcp_timestamps和net.ipv4.tcp_tw_recycle两者都会产生
Linux的/net/ipv4/tcp_ipv4.c
Linux的/include/net/tcp.h
根据上述的逻辑,似乎在负载均衡器或NAT的后方可能会出现问题。
总结
如果不是在LB之下的独立服务器,我认为以下的设定可能会很好。另外,如果仅限于入站通信,也许可以成功减少TIME_WAIT。*tcp_fin_timeout应根据环境进行调整。
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
也许考虑将位于LB下方的WEB服务器等禁用tcp_tw_recycle的设置会更好。
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
这次只关注了从以前就经常出现的三个参数,但由于有很多参数,还存在很大的改进空间,可以更加高效。
默认值似乎是一直没有变化的历史选择,因此我们需要充分理解它的重要性并重新认识。