系统性能调优必知必会
陶辉
智链达 CTO,前阿里云 P8 高级技术专家
36367 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
系统性能调优必知必会
15
15
1.0x
00:00/00:00
登录|注册

09 | 如何提升TCP三次握手的性能?

开启TFO功能
实现原理
信任问题解决
调整accept队列长度
调整重发次数
开启syncookies功能
SYN半连接队列管理
优化三次握手时间
调整重试次数和时间上限
同步序列号的重要性
TFO技术
服务器端优化
客户端优化
思考题
TCP连接状态变化
如何提升TCP三次握手的性能

该思维导图由 AI 生成,仅供参考

你好,我是陶辉。
上一讲我们提到 TCP 在三次握手建立连接、四次握手关闭连接时是怎样产生事件的,这两个过程中 TCP 连接经历了复杂的状态变化,既容易导致编程出错,也有很大的优化空间。这一讲我们看看在 Linux 操作系统下,如何优化 TCP 的三次握手流程,提升握手速度。
TCP 是一个可以双向传输的全双工协议,所以需要经过三次握手才能建立连接。三次握手在一个 HTTP 请求中的平均时间占比在 10% 以上,在网络状况不佳、高并发或者遭遇 SYN 泛洪攻击等场景中,如果不能正确地调整三次握手中的参数,就会对性能有很大的影响。
TCP 协议是由操作系统实现的,调整 TCP 必须通过操作系统提供的接口和工具,这就需要理解 Linux 是怎样把三次握手中的状态暴露给我们,以及通过哪些工具可以找到优化依据,并通过哪些接口修改参数。
因此,这一讲我们将介绍 TCP 握手过程中各状态的意义,并以状态变化作为主线,看看如何调整 Linux 参数才能提升握手的性能。

客户端的优化

客户端和服务器都可以针对三次握手优化性能。相对而言,主动发起连接的客户端优化相对简单一些,而服务器需要在监听端口上被动等待连接,并保存许多握手的中间状态,优化方法更为复杂一些。我们首先来看如何优化客户端。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了在Linux操作系统下如何优化TCP的三次握手流程,提升握手速度。针对客户端和服务器端分别介绍了性能优化的方法,包括调整重试次数和时间上限、调整SYN半连接队列大小、开启syncookies功能以及调整重发次数等。此外,还介绍了如何调整accept队列的长度以及如何判断是否需要调整队列长度。另外,文章还介绍了TCP fast open(TFO)技术如何绕过三次握手发送数据,以及在Linux下如何打开TFO功能。通过对TCP三次握手过程中各状态的意义和优化方法的详细介绍,读者可以快速了解如何在Linux操作系统下提升TCP三次握手的性能。文章内容涵盖了TCP优化的多种方式,为读者提供了丰富的优化方法和技术细节。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《系统性能调优必知必会》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(40)

  • 最新
  • 精选
  • Geek_1386e9
    我在生产系统中确实遇到了accept队列溢出导致的请求超时问题,这种问题确实不容易被发现,服务器cpu、内存、连接数监控指标都正常,只是磁盘读写时间偶尔会偏高,当时为了解决这个问题,我搭建了一个测试环境,客户端用wrk发起请求,服务端用dd模拟磁盘大量读写导致io响应慢。并用blktrace+fio分析io,同时两边用tcpdump抓包,通过抓包数据发现服务端忽略了第三次握手客户端发来的ack(tcp_abort_on_overflow=0),又重发了第二次握手的syn+ack的包,响应超过了客户端的超时时间设置,google后才知道了是因为accept队列溢出的问题,结论就是我们使用的公有云虚拟机因为同宿主机上其他客户的虚拟机io大导致我们的虚拟机磁盘读写时间长,应用程序处理慢,没能及时从accept队列里拿连接处理,导致accept队列溢出,调大accept队列只能缓解溢出情况,提升程序处理速度才能根本解决,后面我们申请了独享的虚拟机,并且换成了共享ssd磁盘,并把io调度算法改成了noop,问题完美解决,性能杠杠滴

    作者回复: 谢谢Geek_1386e9同学的实践分享! 一般可以通过netstat从丢包上检测出,大流量下在生产环境上抓包不易。

    2020-06-04
    2
    57
  • 忆水寒
    本文的干货满满的,虽然都熟悉,但是没有这么底层的优化过。 当网络丢包严重的时候,可以使用快速重传机制。重传时间间隔是指数级退避,直到达到 120s 为止,总时间将近 15 分钟,重传次数默认是 15次 ,重传次数默认值由 /proc/sys/net/ipv4/tcp_retries2 决定。

    作者回复: 谢谢忆水寒的补充!

    2020-05-20
    2
    21
  • Geek_007
    看评论区,很多同学都说是长连接,普通的http keepalive 会不会有坑,三大运营商或者中间网络设备都会将超过一定时间的链接drop掉。如果没有h2这种ping保活的机制,有可能客户端莫名其妙长链接被drop掉,客户端只能依赖超时来感知异常,反倒是影响性能了。

    作者回复: 是的,不只网络设备,一些代理服务器为了减轻自己的负担,也会把长连接断掉,比如Nginx默认关闭75秒没有数据交互的keep alive 长连接

    2020-05-18
    18
  • Jesson
    老师,TFO编程的时候,为什么要改为sendto或者sendmsg啊? 这个地方原理不太懂。

    作者回复: 你好Tango281,非TFO场景下,你大可先调用connect函数,在这里传递服务器地址,再调用send函数发送请求,但在TFO场景下,是不能调用connect函数的,否则就回归正常的三次握手了,所以要使用sendto等函数。

    2020-05-22
    3
    13
  • 凉人。
    做过优化,长连接, 减少time_wait时长,复用time_wait连接

    作者回复: 谢谢凉人的分享

    2020-05-18
    11
  • 那时刻
    使用http的时候,为了减少tcp链接,重复使用已经链接的tcp,设置nginx的keepalive参数。

    作者回复: http/1.1里的keepalive功能是个很好用的优化点^_^

    2020-05-18
    2
    7
  • 半生
    老师,请教一个问题,都是减少tcp握手的代价,那tfo和长链接分别是什么使用场景,或者说,什么场景下,tfo会比长链接性价比更高?

    作者回复: 如果应用层允许使用长连接(比如应用层的超时可能有上限),或者空闲连接占用的内存资源不在乎(长连接不只在内核,在应用层在每连接也要消耗KB级别以上的内存),就使用长连接。 TFO的开启是有前提的,至少两端都要支持。

    2020-09-01
    5
  • 猿人谷
    这篇文章太精彩了,赏心悦目啊

    作者回复: 谢谢^_^

    2020-05-22
    3
  • 感觉小林coding就是抄的这篇,太干货了,😁

    作者回复: ^_^

    2020-12-09
    2
  • Douglas
    【accept队列溢出】这里讲的比较模糊,accept队列溢出。是把已经建立好的连接丢弃, 还是因为队列已满,所以,后续进来的连接直接丢弃呢?

    作者回复: 默认的行为是新进入的报文直接丢弃。这样,如果几秒后accept队列消费掉了,那么客户端超时重发的DATA+ACK到了,连接就会再次建立

    2020-07-19
    4
    2
收起评论
显示
设置
留言
40
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部