TCP 性能优化浅析

前言

TCP 作为一种最常用的传输层协议,它的作用是在不可靠的传输信道上,提供可靠地数据传输。在各层网络协议中,只要有一层协议是可靠的,那么整个网络传输就是安全可靠的。现实中,几乎所有的 HTTP 流量都是经过 TCP 传输。因此,我们要进行 web 性能优化,TCP 是其中的关键一环。要针对 TCP 进行性能优化,就得理解其工作原理。

三次握手

众所周知,建立一次 TCP 连接需要进行三次握手。关于三次握手,一图胜千言。

图1

三次握手给 TCP 带来了很大的延迟,不过这个握手过程是必不可少的。因为如果没有三次握手,有可能会出现一些已经失效的请求包突然又传到服务端,服务端认为这是客户端发起的一次新的连接,于是发出确认包,表示同意建立连接。而客户端并不会有响应,导致服务器出现空等,白白浪费服务器资源。

既然三次握手的过程不可避免,那么我们只能通过重用 TCP 连接,减少三次握手的次数。HTTP 1.1 引入了长连接,通过在请求头中加入 Connection: keep-alive, 来告诉请求响应完毕后,不要关闭连接。不过 HTTP 长连接也是有限制的,服务器通常会设置 keep-alive 超时时间和最大请求数,如果请求超时或者超过最大请求数,服务器会主动关闭连接。

除此之外,TFO(TCP Fast Open,TCP 快速打开)这种机制也被设计用于优化三次握手过程。它通过握手开始时的 SYN 包中的 TFO cookie(一个 TCP 选项)来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的 ACK 包收到之前就开始发送数据。


图2

Linux 3.7 及以后的内核在客户端及服务器中支持 TFO, 对于移动端,Android 和 iOS 9+ 都支持 TFO,不过 iOS 并未默认启用。

PS: 推荐大家装一个 wireshark,可以非常直观的观察到三次握手的过程。


屏幕快照 2018-02-02 下午11.30.33.png

流量控制

流量控制是一种预防发送端向接受端发送过多数据的机制。它的主要目的是为了防止接收端服务过载,从而出现丢包。为了实现流量控制,TCP 连接的每一方都要声明自己的通告窗口(rwnd),表示自己的缓冲区最多能接收多少数据。如果其中一端跟不上对方的发送速度,就通知对方一个较小的窗口。如果窗口大小为 0,应用层必须先清空缓冲区,才能继续接收数据。这就是所谓的滑动窗口协议。

大家可能经常遇到这种情况,自己明明是百兆宽带,实际下载速度每秒却只有几M。这种情况有可能就是通告窗口(rwnd)设置的不合理造成的。最初的 TCP 规范分配给接收窗口大小的字段是 16 位,也就是 64KB(2 的 16 次方)。实际上,rwnd 的大小应该由 BDP(带宽延迟积) 而定。BDP(bit) = bandwidth(b/s) * round-trip time(s)。比如一个 100Mbps 的宽带,RTT 是100 ms,那么 BDP = (100 / 8) * 0.1 = 1.25M。此时,要想提高网络传输吞吐量,rwnd 应该为 1.25 M。

为了解决这个问题,TCP 窗口缩放(TCP Window Scaling)出现了,它将窗口大小由 16 位扩展到 32 位。Linux 上自带了缓冲大小调优机制,如下命令,可以查看 Linux 初始窗口大小:

sysctl net.ipv4.tcp_rmem
// 输出 net.ipv4.tcp_rmem = 4096  87380    6291456
// 从左到右一次为最小值、默认值、最大值

慢启动

流量控制机制可以防止发送端和接收端之间的服务过载,但无法防止任何一端向某个网络的发送数据过载,因此还需要一个估算机制,根据网络环境动态改变数据传输速度,这就是慢启动出现的原因。

慢启动为发送方的 TCP 增加了一个窗口:拥塞窗口(congestion window),记为 cwnd。当与另一个网络的主机建立 TCP 连接时,cwnd 初始化为 1 个 TCP 段。每收到一个 ACK,cwnd 就增加一个 TCP 段。发送端取 cwnd 和 rwnd 中的最小值作为发送上限。可以这样理解,拥塞窗口是发送端使用的流量控制,而通告窗口是接收端使用的流量控制。

一开始 cwnd 为 1,发送方只发送一个 mss(最大报文段长度) 大小的数据包,收到 ack 后,cwnd 加 1,cwnd=2。

此时 cwnd 2,则发送方要发送两个 mss 大小的数据包,发送方会收到两个 ack,则 cwnd 会进行两次加一的操作,则也就是 cwnd+2,则
cwnd=4,也就是 cwnd = cwnd*2。

以此类推,每次 rtt 后,cwnd 都会变成上次发送前的 2 倍。因此,cwnd 的大小是呈指数级在递增。


图3

随着 cwnd 的增加,会发送网络过载,此时会出现丢包。一旦发现有这种问题,cwnd 会成倍减少。


图4

为了减少往返次数,初始拥塞窗口的大小设定就尤为重要。默认情况下(RFC 2581),初始 cwnd 为 4 个 MSS。Google 建议将初始窗口改为 10 个 MSS。根据 Google 的研究,90% 的 HTTP 请求数据都在 16KB 以内,约为 10 个 MSS。

总结

本文介绍了 TCP 的部分工作原理,包括三次握手、流量控制、慢启动,并阐述了 TCP 快速打开、窗口缩放、增加初始拥塞窗口大小等优化手段。内容有点偏理论,还是需要多多实践,才能合理掌握各种优化手段。


参考文献:

  1. 《Web性能权威指南》
  2. 《TCP/IP详解,卷1:协议》
  3. 浅谈TCP优化
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 1.这篇文章不是本人原创的,只是个人为了对这部分知识做一个整理和系统的输出而编辑成的,在此郑重地向本文所引用文章的...
    SOMCENT阅读 13,028评论 6 174
  • TCP/IP协议 作者:xinyuans 本文为参考TCP/IP详解卷一,某些知识点加上了作者自己的理解,如有错误...
    xinyuans阅读 776评论 0 1
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,042评论 0 8
  • 24.1 引言 TCP已经在从1200 b/s的拨号SLIP链路到以太数据链路上运行了许多年。在80年代和90年代...
    张芳涛阅读 1,435评论 0 3
  • 18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将...
    张芳涛阅读 3,324评论 0 13