简介:Linux系统TCP内核参数优化总结
日常运维工作中,会遇到很多TCP相关的问题,网上有很多文章介绍需要优化哪些TCP内核参数,但是并没有很详细说明优化的依据、适用的场景是什么,如果我们不了解各个参数实际的作用,照搬网上的配置到生产环境,很有可能会适得其反,本文从建立连接、数据传输、断开连接三个阶段对涉及到的相关TCP内核参数做出说明并给出优化建议。
图1:TCP连接状态变迁图
1. 建立连接阶段
- net.ipv4.tcp_syn_retries
控制三次握手第一步客户端发送syn得不到服务端响应时重传syn的次数,如果是内网环境,中间链路少,网络稳定,服务端无响应很可能是服务端应用出了问题,重传多次的意义不大,还会加大服务端压力,可以调低重传次数,让客户端尽快去尝试连接其他服务端。 - net.ipv4.tcp_syncookies
开启SYN Cookies,默认开启,建议保持默认值,可以提升SYN Flood攻击的防护能力。 - net.ipv4.tcp_synack_retries
控制三次握手第二步服务端发送syn+ack得不到客户端响应时重传syn+ack的次数,如果是内网环境,中间链路少,网络稳定,客户端无响应很可能是客户端出了问题,重传多次的意义不大,可以调低重传次数。 - net.ipv4.tcp_max_syn_backlog
控制半连接队列大小,所谓半连接是指还没有完成TCP三次握手的连接。服务端收到了客户端的SYN包后,就会把这个连接放到半连接队列中,然后再向客户端发送SYN+ACK,为了应对新建连接数暴增的场景,建议调大,半连接队列溢出观察方法:netstat -s | grep "SYNs to LISTEN" - net.core.somaxconn
全连接队列=min(somaxconn,backlog),所谓全连接,是指服务端已经收到客户端三次握手第三步的ACK,然后就会把这个连接放到全连接队列中,全连接队列中的连接还需要被 accept()系统调用取走,服务端应用才可以开始处理客户端的请求,建议适当调大,全连接队列溢出观察方法:netstat -s | grep "listen queue" - net.ipv4.tcp_abort_on_overflow
当全连接队列满了之后,新的连接就会被丢弃掉。服务端在丢弃新连接时,默认行为是直接丢弃不去通知客户端,有的时候需要发送reset来通知客户端,这样客户端就不会再次重试,至于是否需要给客户端发送reset,是由tcp_abort_on_overflow参数控制,默认为0,即不发送reset给客户端,如非特殊需求,建议保持默认值。
2. 数据传输阶段
- net.ipv4.tcp_wmem
tcp发送缓冲区大小,包含min、default、max三个值,内核会控制发送缓冲区在min-max之间动态调整,可根据实际业务场景和服务器配置适当调大,如果设置了socket的SO_SNDBUF,动态调整功能失效,一般不建议设置。 - net.core.wmem_max
socket发送缓冲区的最大值,需要设置net.core.wmem_max的值大于等于 net.ipv4.tcp_wmem的max值。 - net.ipv4.tcp_mem
系统中所有tcp连接最多可消耗的内存,有三个值,当TCP总内存小于第1个值时,不需要内核进行自动调节,在第1和第2个值之间时,内核开始调节缓冲区的大小,大于第3个值时,内核不再为TCP分配新内存,此时无法新建连接,需要注意的是,三个值的单位都是内存页,也就是4KB。 - net.ipv4.tcp_rmem
tcp接收缓冲区大小,包含min、default、max三个值,内核会控制接收缓冲区在min-max之间动态调整,可根据实际业务场景和服务器配置适当调大,如果设置了socket的 SO_RECVBUF或者关闭了net.ipv4.tcp_moderate_rcvbuf,动态调整功能失效。 - net.core.rmem_max
socket接收缓冲区的最大值,需要设置net.core.rmem_max的值大于等于net.ipv4.tcp_rmem 的max值。 - net.ipv4.tcp_moderate_rcvbuf
接收缓冲区动态调整功能,默认打开,建议保持默认配置。 - net.ipv4.tcp_window_scaling
扩充滑动窗口,tcp头部中,窗口字段只有2个字节,最多只能达到2的16次方,即65535字节大小的窗口,打开此开关可以扩充窗口大小,默认打开,建议保持默认配置。 - net.ipv4.tcp_keepalive_probes
keepalive探测失败后通知应用前的重试次数,建议适当调低。 - net.ipv4.tcp_keepalive_intvl
keepalive探测包的发送间隔时间,建议适当调低。 - net.ipv4.tcp_keepalive_time
最后一次数据包到keepalive探测包的间隔时间,建议适当调低。 - net.ipv4.tcp_available_congestion_control
查看内核支持的拥塞控制算法。 - net.ipv4.tcp_congestion_control
配置拥塞控制算法,默认cubic,内核4.9版本后支持BBR,弱网络条件下建议配置成BBR。
3. 断开连接阶段
- net.ipv4.tcp_fin_timeout
是从Fin_WAIT_2到TIME_WAIT的超时时间,长时间收不到对端FIN包,大概率是对端机器有问题,不能及时调用close()关闭连接,建议调低,避免等待时间太长,资源开销过大。 - net.ipv4.tcp_max_tw_buckets
系统TIME_WAIT连接的最大数量,根据实际业务需要调整,超过最大值后dmesg会有报错TCP: time wait bucket table overflow。 - net.ipv4.tcp_tw_reuse
允许TIME_WAIT状态的连接占用的端口用到新建连接中,客户端可开启。 - net.ipv4.tcp_tw_recycle
开启后,TIME_WAIT状态的连接无需等待2MSL时间就可用于新建连接,在NAT环境下,开启tcp_tw_recycle参数会触发PAWS机制导致丢包,建议不开启,事实上,内核在4.1版本后就把这个参数删除了。
我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。
原文链接:https://developer.aliyun.com/article/796145?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。