未优化前服务器的状态[[email protected]~ "o">]"c">#netstat-na|awk'{print$6}'|sort|uniq-c|sort-nr490ESTABLISHED44SYN_RECV34LAST_ACK10CONNECTED5LISTEN3CLOSE_WAIT21established)1and1I-Node1Foreign17894382163431625016241139375081283768211863理论图
放一张图,要搞清楚怎么调整参数,这张图相当重要。看不太明白不要紧,后面会详细讲到这张图
序列号 | CPU | RAM | HDD | 带宽 | 售价(美元) | 免费试用 |
---|---|---|---|---|---|---|
香港服务器1 | E5-2620 | 32G | 1T HDD | 50M/无限流量 | $196.00 | 立即申请 |
香港服务器2 | E5-2650 | 32G | 1T HDD | 50M/无限流量 | $256.00 | 立即申请 |
香港服务器3 | E5-2680 | 32G | 1T HDD | 50M/无限流量 | $316.00 | 立即申请 |
香港服务器4 | E5-2690 | 32G | 1T HDD | 50M/无限流量 | $336.00 | 立即申请 |
香港服务器5 | E5-2697 | 32G | 1T HDD | 50M/无限流量 | $376.00 | 立即申请 |
香港服务器6 | E5-2620*2 | 32G | 1T HDD | 50M/无限流量 | $376.00 | 立即申请 |
香港服务器7 | E5-2650*2 | 32G | 1T HDD | 50M/无限流量 | $436.00 | 立即申请 |
香港服务器8 | E5-2680*2 | 32G | 1T HDD | 50M/无限流量 | $476.00 | 立即申请 |
香港服务器9 | E5-2690*2 | 32G | 1T HDD | 50M/无限流量 | $556.00 | 立即申请 |
香港服务器10 | E5-2697*2 | 32G | 1T HDD | 50M/无限流量 | $596.00 | 立即申请 |
香港服务器11 | E5-2680v4*2 | 32G | 1T HDD | 50M/无限流量 | $696.00 | 立即申请 |
香港服务器12 | E5-2698v4*2 | 32G | 1T HDD | 50M/无限流量 | $796.00 | 立即申请 |
优化经验值
转一个金山张宴的贴子对/etc/sysctrl.conf的优化参数,后面会仔细介绍参数。
#Addnet.ipv4.tcp_max_syn_backlog=65536net.core.netdev_max_backlog=32768net.core.somaxconn=32768net.core.wmem_default=8388608net.core.rmem_default=8388608net.core.rmem_max=16777216net.core.wmem_max=16777216net.ipv4.tcp_timestamps=0net.ipv4.tcp_synack_retries=2net.ipv4.tcp_syn_retries=2net.ipv4.tcp_tw_recycle=1#net.ipv4.tcp_tw_len=1net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_mem"o">=94500000915000000927000000net.ipv4.tcp_max_orphans=3276800#net.ipv4.tcp_fin_timeout=30#net.ipv4.tcp_keepalive_time=120net.ipv4.ip_local_port_range=102465535TCP三次握手以及其中的各种状态:
SYN(Synchronize Sequence Numbers)。
同步序列编号
ACK (ACKnowledge Character)
在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误。
=================================client发送syn至server此时客户端的状态变为SYN_SENTclient( "nv">syn=j "o">)====>serverserver收到syn,并发送syn+ack到client,这种过程server状态由listen变为SYN_RECV,并等待客户端再次发来ack数据client<=========server "o">(syn "o">=k,ack=j+1"o">)client接收到server发过来的syn+ack,并向服务端发送ACK,服务器接收后由SYN_RECV变为ESTABLISHEDclient(ACK "o">(ack "o">=k+1))========>server此种情况下,服务端在三次握手的变迁是LISTEN->SYN_RECV->ESTABLISHED客户端的三次握手的变迁是SYN_SENT->ESTABLISHED====================================注意问题
一、首先server有个用来接收client发送的syn并对syn进行排队的队列,如果队列满了,新的请求不被接受。
此队列长度控制参数:
net.ipv4.tcp_max_syn_backlog
对应文件(/proc/sys/net/ipv4/tcp_max_syn_backlog ) 默认是1024
1[[email protected] "o">]"c">#cat/proc/sys/net/ipv4/tcp_max_syn_backlog21024
二、然后是SYN-ACK重传:当server向client发送syn+ack没有收到相应,server将重传,然后再重传。。。控制这个重传次数的参数是
tcp_synack_retries
对应文件(/proc/sys/net/ipv4/tcp_synack_retries)默认值是5,对应于180秒左右时间
1[[email protected]~ "o">]"c">#cat/proc/sys/net/ipv4/tcp_synack_retries25
关于tcp_synack_retries的英文解释:The maximum number of times a SYN/ACK segment for a passive TCPconnection will be retransmitted. This number should not be higherthan 255. The default value is 5.
备注:与此相对应的client的参数是:tcp_syn_retriesThe maximum number of times initial SYNs for an active TCPconnection attempt will be retransmitted. This value should not behigher than 255. The default value is 5, which corresponds toapproximately 180 seconds.
三、关于tcp_syncookies
SYN Cookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范SYNFlood攻击的一种手段。它的原理是,在TCP服务器收到TCP SYN包并返回TCPSYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值。在收到TCPACK包时,TCP服务器在根据那个cookie值检查这个TCPACK包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。
1[[email protected]~ "o">]"c">#cat/proc/sys/net/ipv4/tcp_syncookies21典型syn_recv故障处理
如果服务器syn_recv的条数过多,可以采取的操作是:
减少server==>client重传syn+ack的次数。
加大syn队列长度,防止无法响应新的连接
1echo"s2">"net.ipv4.tcp_max_syn_backlog=4096">>/etc/sysctl.conf2echo"s2">"net.ipv4.tcp_synack_retries=1">>/etc/sysctl.conf3sysctl-p
当受到syn攻击的时候,启用syn-cookie(默认启用,在/etc/sysctl.conf里本身就有参数配置)
1"nb">echo1>/proc/sys/net/ipv4/tcp_syncookiesTCP四次握手
下面说tcp/ip的第四次握手,分析主动关闭和被动关闭两种。
A:因为如果是CLIENT端主动断掉当前连接,那么双方关闭这个TCP连接共需要四个packet:
setupClient--->FIN(M)--->Serverclient发送一个FIN给server,(说它不跟你玩了),client由ESTABLISHED->FIN_WAIT1Client<---ACK(M+1"o">)<---ServerSERVER收到fin后发送ack确认(拿出两人信物),状态由ESTABLISHED->close_waitclient收到server的ack确认,只是改变状态ESTABLISHED->FIN_WAIT1->FIN_WAIT2,继续等server发送数据。Client<--FIN(N"o">)<--Serverserver继续发送FIN到client(好就不玩了吧),状态ESTABLISHED->close_wait->LAST_ACK,等待client发送ack做最后的确认Client-->ACK(N+1"o">)-->Serverclient收到FIN,马上发送ack确认,状态ESTABLISHED->FIN_WAIT1->FIN_WAIT2->TIME_WAIT[2MSL超时]->closedserver收到ack确认,状态ESTABLISHED->close_wait->LAST_ACK->CLOSED.keepalive_timeout
client关闭连接很好想,有点要搞清楚的是,server端什么时候会发起丢掉连接的操作:
有些是应用程序控制的。nginx.conf为例
keepalive_timeout0;[[email protected]~"o">]#curl-Ihttp://www.XXX.comConnection:closekeepalive_timeout600;[[email protected]~"o">]#curl-Ihttp://www.XXX.comConnection:keep-alive
这种规定了连接时间的,到了时间连接会断掉。
如果没有规定的,则按照系统keepalived定时器的设置进行,具体参数如下:
[[email protected]~"o">]#sysctl-a|greptcp_keepalivenet.ipv4.tcp_keepalive_intvl=75net.ipv4.tcp_keepalive_probes=9net.ipv4.tcp_keepalive_time=30
连接两端一直没发送数据,间隔半分钟,后开始第一次探测,间隔75秒后第二次探测,探测9次,最后放弃连接。
四种状况其实最后一种没什么意义,能考虑到下面三种就行了
1client正常,每进行一次通讯,net.ipv4.tcp_keepalive_time重置一次。
2一直到7200+75*9后也无法获取client反馈信息,则认为client已经关闭并终止连接(连接超时)
3client重启,收到探测后返回一个复位(RST)信息。server收到后终止连接(连接被对方复位)
典型timewait故障处理
一、网站服务器访问速度变慢,查看网站服务器连接,看到连接至数据库的连接中出现大量time_wait,多达400个。分析是网站服务器定时任务做大量读取数据库操作的时候产生的。此情况出现在client.
根据上面讲的,time_wait对应2MSL超时,什么是2MSL?,是在client在四次握手的时候最后发送了ack确认给服务器后必然经过的一个时间。TIME_WAIT状态的目的是为了防止最后client发出的ack丢失,让server处于LAST_ACK超时重发FIN。配置2MSL时间长短的服务器参数,但这里不是优化的重要参数,我们需要的是Time_wait的连接可以重用,并且能迅速关闭。
2MSl的解释:
MSL是MaximumSegmentLifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是timetolive的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。562MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。78TTL与MSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL。1[[email protected]~ "o">]"c">#sysctl-a|greptime|grepwait2net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=1203net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=604net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120
关于 ip_ct_tcp_timeout_time_wait
13.7.15.ip_ct_tcp_timeout_time_wait23Theip_ct_tcp_timeout_time_waitvariabledefinesthetimeoutvalueoftheTIME-WAITstateasdefinedbyRFC793.ThisisthefinalstatepossibleinaTCPconnection.Whenaconnectionisclosedinbothdirections,theserverandcliententerstheTIME-WAITstate,whichisusedsothatallstalepacketshavetimetoentertheclientorserver.Oneexampleoftheusageofthismaybeifpacketsarereorderedduringtransitbetweenthehostsandwindsupinadifferentorderateitherside.Insuchacase,thetimewindowdefinedintheip_ct_tcp_timeout_time_waitvariableisusedsothatthosepacketsmayreachtheirdestinationsanyways.Whenthetimeoutexpires,theconntrackentryisdestroyedandweenterthestateCLOSED,whichmeansthatthereisnoconntrackdataatallfortheconnectioninquestion.45Thedefaultvalueoftheip_ct_tcp_timeout_time_waitvariableissetto120seconds,or2minutes.Youshouldgenerallywanttokeepthisvalueifyouknowthatyouliveonaconnectionthatisslowandthatoftenreordersthepacketsinquestion.Ifthisvalueistoolowyouwilloftenexperiencecorruptdownloadsormissingdataindownloadeddata,youshoulddefinitelyavoidtuningthisvaluedowninsuchacase,andyoumaymostdefinitelyconsiderraisingthetimeoutofthisvalueinsuchcase.Ifyouneverexperiencesuchbehaviouroranyotherproblemslikethat,youmaymostprobablylowerthisvaluesothatconntrackentriesdiefaster,andhencerecycletheconntrackentryspacefaster.63.7.15.3.7.15.ip_ct_tcp_timeout_time_wait
如何解决?
控制重用和迅速回收的参数是net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle。
这两个参数的具体英文解释和作用等我查到了再补充,网上讲的也不怎么清楚。
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAITsockets重新用于新的TCP连接,默认为0
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAITsockets的快速回收,默认为0。
1echo"s2">"net.ipv4.tcp_tw_reuse=1">>/etc/sysctl.conf2echo"s2">"net.ipv4.tcp_tw_recycle=1">>/etc/sysctl.conf3sysctl-p出现FIN_WAIT_2状态
现象描述
服务器端运行服务9090的c,或java程序用killall -9 服务名 kill掉后,出现
FIN_WAIT_2状态,新的服务无法启动。因为这个状态占据了服务端口。时间默认1分钟。
1[[email protected]~ "o">]"c">#sysctl-a|greptime|grepfin2net.ipv4.tcp_fin_timeout=60
主要就是服务端主动发起关闭,此时服务端相当于一个client,在最后等对方发送最后一个FIN的却一直等不到,直至超时,控制这个超时的时间参数是tcp_fin_timeout
tcp_fin_timeout(0S)
Howmanysecondstowait"k">forafinalFINpacketbeforethesocketisforciblyclosed.ThisisstrictlyaviolationoftheTCPspecification,butrequiredtopreventdenial-of-service(DoS)attacks.Thedefaultvaluein2.4kernelsis60,downfrom180in2.2.备注:TCP_LINGER2(tcpsocket编程选项 "o">)ThelifetimeoforphanedFIN_WAIT2statesockets.Thisoptioncanbeusedtooverridethesystemwidesysctltcp_fin_timeoutonthissocket.Thisisnottobeconfusedwiththesocket(7)leveloptionSO_LINGER.Thisoptionshouldnotbeusedincodeintendedtobeportable.1echo"s2">"net.ipv4.tcp_fin_timeout=30">>/etc/sysctl.conf2sysctl-p3"c">#echo30>/proc/sys/net/ipv4/tcp_fin_timeout
此外,还有控制tcp发送缓冲区,接收缓冲区大小的设置,能够使用端口范围的设置。
1[[email protected]~ "o">]"c">#cat/proc/sys/net/ipv4/ip_local_port_range23276861000
这个是本地连接外地端口时开的动态端口,个人觉得默认就够了。如果有很频繁的要连接外面端口,可以设大。
1"c">#echo"500065535">/proc/sys/net/ipv4/ip_local_port_range2echo"s2">"net.ipv4.ip_local_port_range=500065000">>/etc/sysctl.conf3sysctl-p总结经验值net.ipv4.tcp_keepalive_time=300net.ipv4.tcp_syncookies=1net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_tw_recycle=1net.ipv4.ip_local_port_range=500065000