TCP优化学习笔记(二):参数调优

目录

TCP 的三次握手

状态解释

TCP 四次挥手

状态解释

参数调优

TCP连接优化

time-wait调优:减少time-wait

参数说明:

长连接

Nginx TCP配置优化

tcp_nodelay 

tcp_nopush

sendfile

 

TCP 的三次握手

状态解释

  • CLOSED: 表示初始状态。
  • LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受连接
  • SYN_RCVD:表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。
  • SYN_SENT:这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
  • ESTABLISHED:表示连接已经建立

完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:

  • 未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到 SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目, 服务器进入ESTABLISHED状态。
  • Backlog参数:表示未连接队列的最大容纳数目。
  • SYN-ACK 重传次数:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超 过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。
  • 半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

TCP 四次挥手

状态解释

  • FIN_WAIT_1:FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。
  • FIN_WAIT_2:FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
  • TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
  • CLOSING:正常情况下,发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
  • CLOSE_WAIT:表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
  • LAST_ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。
     

参数调优

开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_syncookies = 1

系统默认的TIMEOUT时间。
net.ipv4.tcp_fin_timeout = 5

当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟(20*60s)
net.ipv4.tcp_keepalive_time = 1200

表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000
net.ipv4.ip_local_port_range = 10000 65000

SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数
net.ipv4.tcp_max_syn_backlog = 8192系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默认为180000,改为5000
net.ipv4.tcp_max_tw_buckets = 5000

TCP连接优化

time-wait调优:减少time-wait

time-wait会发生在发起断开请求的一端。一般这样的服务器会是我们的代理节点或web服务器,因为他们需要作为客户端向后端节点发起访问。而系统进入time-wait后会等待60s的时间,在这段时间内,系统不会释放socket,仍然会占据端口,这样对于高并发的业务非常不利。

对此我们就需要对处于time-wait状态的socket进行快速回收。

参数说明:

开启重用:net.ipv4.tcp_tw_reuse

允许将TIME-WAIT sockets重新用于新的TCP连接,默认关闭;当启用tcp_tw_reuse时,在TIME_WAIT状态下的套接字可以在它们过期之前使用,并且内核将尝试确保没有关于TCP序列号的冲突。如果启用tcp_timestamps(a.k.a. PAWS,防止包装序列号),它将确保这些冲突不会发生。但是,需要在服务器两端都启用TCP时间戳。

开启TCP连接中TIME-WAIT sockets的快速回收:net.ipv4.tcp_tw_recycle

启用tcp_tw_recycle时,内核变得更加积极回收time wait,并且将对远程主机使用的时间戳作出假设判断。它将跟踪具有TIME_WAIT状态的连接的每个远程主机使用的最后时间戳),并允许在时间戳正确增加的情况下重新使用套接字。但是,如果主机使用的时间戳发生变化(即时间回退),则SYN数据包将被静默地丢弃,并且连接不会建立(您将看到类似于“连接超时”的错误)。

开启时间戳:tcp_timestamps 

Timestamps 用在其它一些东西中﹐可以防范那些伪造的 sequence 号码。一条1G的宽带线路或许会重遇到带 out-of-line数值的旧sequence 号码(假如它是由于上次产生的)。Timestamp 会让它知道这是个 ‘旧封包’。(该文件表示是否启用以一种比超时重发更精确的方法(RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项。)
 

提示:如果关闭tcp_timestamp, tcp_tw_recycle则不能开启。

长连接

长连接会加快访问速度,减少time-wait,但长连接会长时间占用socket。

Nginx TCP配置优化

在nginx的配置文件中有相关TCP连接的优化,分别是sendfile,tcp_nopush和tcp_nodelay。

sendfile on|off;  # 是否启用文件快速传输
tcp_nopush on|off; # 是否缓存数据后集中发送,适用于大文件传输  
tcp_nodelay on|off; # 是否立即发送数据包,使用于即时性传输

tcp_nodelay 

TCP_NODELAY选项允许绕过Naggle算法,然后尽快发送数据。当下载完整的网页时,TCP_NODELAY可以在每个HTTP请求上节省更多的时间,这样可以有更佳的用户体验。 在在线游戏或高频交易时的场景,即使以相对网络饱和的代价,摆脱延迟至关重要。

Nginx在HTTP keepalive连接上使用TCP_NODELAY。 keepalive连接是在发送数据后保持打开几次的套接字。 keepalive允许发送更多的数据,而不会启动新的连接,并重复每次HTTP请求的TCP 3次握手方式。 这样可以节省重新创建socket的时间,因为每次数据传输后都不会切换到FIN_WAIT。 Keep-alive是HTTP 1.0和HTTP 1.1默认行为的一个选项。

tcp_nopush

在Nginx上,配置选项tcp_nopush与tcp_nodelay相反。 不是优化延迟,但是它可以优化一次发送的数据量,和Nagle算法非常接近。

TCP_NOPUSH会调用tcp_cork函数,tcp_cork函数会阻塞数据,直到数据包到达MSS的长度,MSS长度等于MTU减去IP数据包的40(IPV4)或60(IPV6)字节,和Nagle算法不同的是,TCP_CORK软件将等待的时间上限设置为200毫秒,而不是等待上个数据包的ACK。 如果达到上限,则排队的数据将自动传输。

TCP(7)联机帮助页解释说TCP_NODELAY和TCP_CORK是互斥的,但是Linux 2.5.9以后的版本中两者可以兼容。

在Nginx的配置中,sendfile和tcp_nopush必须配合使用。

sendfile

Nginx之所以在静态文件的传输上有很高的性能,主要原因就在于这里所说的三个参数。

 Nginx的sendfile选项可以使用sendfile(2)来处理与发送文件相关的所有内容。

sendfile(2)允许在文件描述符中直接在内核空间中传输数据,节省大量资源:

  • sendfile是一个系统调用,这意味着在内核空间内执行,因此没有昂贵的上下文切换。

  • 替换了read和write两者的组合。

  • 允许零拷贝,这意味着通过DMA从块设备内存直接写入内核缓冲区。

如果nginx是在为本地存储的静态文件提供服务,则sendfile对于加快Web服务器响应至关重要。 但是,如果使用Nginx作为反向代理来从应用程序服务器提供页面,则可以禁用它。 除非在tmpfs上提供微型缓存。 


参考:

TCP参数调优详解https://blog.csdn.net/erlib/article/details/50236919

TCP连接优化https://blog.51cto.com/tryingstuff/1961464

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值