博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MEMCACHE TIME_WAIT过多的解决方法
阅读量:6183 次
发布时间:2019-06-21

本文共 4982 字,大约阅读时间需要 16 分钟。

hot3.png

环境:

web: LNMP

mc: memcache

2台机器,相对于memcache服务,web为客户端,mc为服务端

现象:

客户端上11211端口有4W多个TIME_WAIT

服务端正常

我们先查看一下我们现在的tcp连接情况

显示套接字使用摘要(优化后)

ss -sTotal: 1231 (kernel 1447)TCP:   1910 (estab 1020, closed 796, orphaned 83, synrecv 0, timewait 796/0), ports 1065Transport Total     IP        IPv6*         1447      -         -        RAW       0         0         0        UDP       2         2         0        TCP       1114      1114      0        INET      1116      1116      0        FRAG      0         0         0

或 

watch -n1 'cat /proc/net/sockstat'Every 1.0s: cat /proc/net/sockstat                                                                                                                                                    Sun Apr  8 11:07:44 2018sockets: used 1232TCP: inuse 1097 orphan 69 tw 1017 alloc 1098 mem 182UDP: inuse 2 mem 0UDPLITE: inuse 0RAW: inuse 0FRAG: inuse 0 memory 0

再看tcp连接情况(优化后)

netstat -n | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'TIME_WAIT 1378FIN_WAIT1 33FIN_WAIT2 237ESTABLISHED 962SYN_RECV 1CLOSING 1LAST_ACK 14

查看TIME-WAIT状态连接的内存占用,内存占用还是蛮小的

slabtop -o | grep -E '(^  OBJS|tw_sock_TCP|tcp_bind_bucket)'  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                     6018   1262  20%    0.06K    102       59       408K tcp_bind_bucket          3870   1860  48%    0.25K    258       15      1032K tw_sock_TCP

开始分析

TIME_WAIT是通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态,此时TCP连接还没释放的,需要一个2MSL(2个最长报文生存时间),在高并发情况下(短连接),就会堆积很多TIME_WAIT,(客户端TCP端口数量由net.ipv4.ip_local_port_range取值,假设有42000个TIME_WAIT,那么每秒有700个连接),当TIME_WAIT产生的速度比不上销毁的速度,那势必造成端口不够用(TCP关闭后才不会占用端口),客户端端口不够用了,就无法建立连接!服务端端口不够用了,就会拒绝连接!也无法提供更高的并发。在我们的环境下,WEB是客户端,MC是服务端,大多数服务器端一般执行被动关闭,服务器不会进入TIME_WAIT状态,这也就说明为什么服务端没有大量的time-wait。

在linux中,MSL写死了

 /usr/src/kernels/2.6.32-696.16.1.el6.x86_64/include/net/tcp.h

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT

                                  * state, about 60 seconds     */

既然知道怎么产生TIME_WAIT了,那就好解决了。

1.web使用长连接

nginx使用upstream,指明http1.1协议(默认长连接),并且设置header Connnction=""

       proxy_http_version 1.1;

       proxy_set_header Connection "";

如何提高更高的并发?

1.提供多个IP

2.减少2MSL时间,也就是启用time-wait的重用和快速回收!

客户端(web)

net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_timestamps = 1

MC作为服务端关闭tw_reuse,tw_recycle,开启timestamps(网上并没有写到这个参数是因为默认是开启的)

net.ipv4.tcp_tw_reuse = 0net.ipv4.tcp_tw_recycle = 0net.ipv4.tcp_timestamps = 1

来看看几个TCP参数的解释

通过cat /proc/sys/net/ipv4/**  查看TCP连接的回收:net.ipv4.tcp_timestamps = 1#开启TCP时间戳#以一种比重发超时更精确的方法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。默认1net.ipv4.tcp_tw_reuse = 1#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle = 1#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。#在NAT(Network Address Translation)网络下,这个选项不推荐启用,会导致大量的TCP连接建立错误。net.ipv4.tcp_fin_timeout = 60#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。默认60,网上大部分写30net.ipv4.tcp_max_tw_buckets = 180000#表示系统同时保持TIME_WAIT套接字的最大数量,默认值(262144|5000)#每个TIME_WAIT连接占用内存很少,无需修改---------以下参数为其他TCP优化建议,建议,建议-----------TCP连接的保持:net.ipv4.tcp_keepalive_time = 60#TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。缺省是2小时。net.ipv4.ip_local_port_range = 1024  65535#表示用于向外连接的端口范围。缺省情况下很小:32768到61000 #注意!在高并发端口较小的情况下,可能导致在这区间的服务启动不起来,可使用缺省值。net.ipv4.tcp_keepalive_probes = 9#TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适)net.ipv4.tcp_keepalive_intvl = 75#探测消息发送的频率,乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒,也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值)TCP的连接管理:net.ipv4.tcp_syncookies = 0#表示是否打开TCP同步标签(syncookie),内核必须打开了CONFIG_SYN_COOKIES项进行编译,同步标签可以防止一个套接字在有过多试图连接到达时引起过载。可防范少量的syn攻击,默认为0,表示关闭。net.ipv4.tcp_synack_retries = 2#tcp_synack_retries 显示或设定 Linux 核心在回应 SYN 要求时会尝试多少次重新发送初始 SYN,ACK 封包后才决定放弃。这是所谓的三段交握 (threeway handshake) 的第二个步骤。即是说系统会尝试多少次去建立由远端启始的 TCP 连线。tcp_synack_retries 的值必须为正整数,并不能超过 255。因为每一次重新发送封包都会耗费约 30 至 40 秒去等待才决定尝试下一次重新发送或决定放弃。tcp_synack_retries 的缺省值为 5|6,即每一个连线要在约 180 秒 (3 分钟) 后才确定逾时。net.ipv4.tcp_retries1 = 3#该变量设置放弃回应一个tcp连接请求前,需要进行多少次重试。缺省值是3。net.ipv4.tcp_retries2 = 15#控制内核向已经建立连接的远程主机重新发送数据的次数,低值可以更早的检测到与远程主机失效的连接,因此服务器可以更快的释放该连接,可以修改为5net.ipv4.tcp_max_syn_backlog = 819200#每一个连接请求(SYN报文)都需要排队,直至本地服务器接收,该变量就是控制每个端口的 TCP SYN队列长度的。如果连接请求多余该值,则请求会被丢弃,可修改为819200,容纳更多等待连接的网络连接数,缺省值为2048|1024

总结:

1. tw_reuse,tw_recycle 必须在客户端服务端开启timestamps才管用(timestamps 默认开启)

2. tw_reuse,tw_recycle 在服务端上不需要开启。

3. tw_reuse,tw_recycle 必须在客户端上开启

4. 为何net.ipv4.tcp_tw_recycle = 1 在NAT下不建议开启?

比如你的负载层lvs是使用nat模式

当多个客户端通过NAT方式联网并与服务端交互时,服务端看到的是同一个IP,由于这些客户端的时间戳可能存在差异,所以从服务端的视角看,便可能出现时间戳错乱的现象,进而直接导致时间戳小的数据包被丢弃。

 

参考资料:

记一次TIME_WAIT网络故障   

https://huoding.com/2012/01/19/142

Coping with the TCP TIME-WAIT state on busy Linux servers

https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux

不要在linux上启用net.ipv4.tcp_tw_recycle参数 

http://www.cnxct.com/coping-with-the-tcp-time_wait-state-on-busy-linux-servers-in-chinese-and-dont-enable-tcp_tw_recycle/?utm_source=tuicool&utm_medium=referral

转载于:https://my.oschina.net/longquan/blog/1607414

你可能感兴趣的文章
调查 | 大多数企业漏洞根植在固件中
查看>>
大数据专家:大数据7大最奇特应用
查看>>
Commvault将未来押注在软件定义存储上
查看>>
《社交网站界面设计(原书第2版)》——3.11 发送邀请
查看>>
我与云计算大会的三天
查看>>
《PIC微控制器项目设计:C语言》一2.3 指针
查看>>
Forrester最佳案例:西班牙银行的创新计划
查看>>
Gartner:大数据宣传在商务智能市场成效不明显
查看>>
黑科技:Mellanox Multi-Host技术打通数据中心任督二脉
查看>>
国内企业加快实现数据驱动型战略转型的创新驱动力
查看>>
徐伟宏:要基于大数据去经营顾客
查看>>
英国数据保护规则将与欧盟保持一致
查看>>
花170美元,我了解了消费级间谍软件的世界
查看>>
IBM助力本土零售商 赢在全渠道时代
查看>>
关于Web Workers你需要了解的七件事
查看>>
开源ERP软件Odoo提速指南
查看>>
太神了!电脑不连网靠硬盘震动也能盗取数据
查看>>
Gartner陈勇:中国企业更积极探索双模IT
查看>>
我的 OpenStack 代码贡献初体验
查看>>
手机流量偷跑调查:使用习惯不当或软件出问题
查看>>