原文: https://jkchao.cn/article/5a2...
TCP 负责在不可靠的传输信道之上提供可靠的抽象层,向应用层隐藏了大多数网络通讯的复杂性能,好比丢包重发、按需发送、拥塞控制及避免、数据完整,等等。采用 TCP 数据流能够确保发送的全部字节可以完整地被接收到,并且客户端的顺序也同样。算法
可是 TCP 设计并未过多顾及时间,由此给浏览器 Web 性能带来了挑战。浏览器
全部 TCP 链接一开始都必须通过三次握手。客户端与服务器在交换应用数据以前,必须就起始分组序列号,以及其余一些链接相关的细节达成一致。处于安全考虑,序列号由两端随机生成。缓存
客户端选择一个随机序列号 x,并发送一个 SYN 分组,其中可能还包含 TCP 标志和选项。安全
服务器给 x 加 1,并选择本身的一个随机序列号 y,追加本身的标志和选项,而后返回响应。服务器
客户端给 x 和 y 加 1,并发送握手期间的最后一个 ACK 分组。cookie
客户端能够在发送 ACK 分组以后当即发送数据,而服务器必须等接收到 ACK 分组以后发送数据。网络
每一个 TCP 链接都要通过三次握手,假若客户端与服务器距离过长,会形成很是大的性能影响。于是,提高 TCP 性能关键在于想办法重用链接。并发
为解决这个问题,人们在积极寻找各类方案,其中长连接(Keep-Alive)、负载均衡、TFO(tcp fast open)即是其中的一些解决办法。负载均衡
Keep-Alive,HTTP 1.1 以后默认开启,指在一个 TCP 链接中能够持续发送多份数据而不会断开链接。tcp
基本原理:客户端(如:ClientA)与负载均衡设备之间进行三次握手并发送 HTTP 请求。负载均衡设备收到请求后,会检测服务器是否存在空闲的长连接,若是不存在,服务器将创建一个新链接。当 HTTP 请求响应完成后,客户端与负载均衡设备协商关闭链接,而负载均衡则保持与服务器之间的这个链接。当有其余客户端(如:ClientB)须要发送 HTTP 请求时,负载均衡设备会直接向服务器之间保持的这个空闲链接发送 HTTP 请求,避免来因为新建 TCP 链接形成的延时和服务器资源耗费。
尽管开启了长连接,但是依然有35%的请求是从新发起一条链接,而握手会形成必定的延迟,TFO 的目标就是为了去除这个延迟,在三次握手期间也能交换数据。
基本原理:
拥塞:即对供不该求,对资源的需求超过了可用的资源,网络性能降低,整个网络的吞吐量随之负荷的增大而减少,甚至会发生拥塞崩溃的现象。
为了减缓网络拥塞现象,TCP 加入许多机制用来控制双向发送数据的速度。如流量监控、拥塞控制、拥塞预防机制等。
流量控制是一种预防发送端过多向接收端发送数据的机制。
滑动窗口是实现流量控制的一种方法,一个简单例子:
设 A 向 B 发送数据。在创建链接时,B 告诉了 A:“个人接收窗口值 rwnd = 400“ (rwnd: receiver window),所以,发送方的发送窗口不能超过接收方给出的接收窗口的数值。TCP 窗口的单位时字节,并非报文段。设每一个报文段的字节长 100,而数据报文段序号的初始值为 1,大写 ACK 表示首部中的确认位 ACK,小写 ack 表示确认字段的值 ack。
从图中能够看出,B 进行了三次流量控制。第一次把窗口减小到 rwnd = 300,第二次又减小到了 rwnd = 100,最后减到 rwnd = 0,即不容许发送数据了。
当 rwnd = 0 时,则意味着必须由应用层先清空缓存区,才能接收剩余数据。这个过程贯穿于每一个 TCP 链接的整个生命周期:每一个 ACK 分组都会携带相应的最新的 rwnd 值,以便两端动态调整数据流,使之适应发送端和接收段的容量及处理能力。
尽管流量监控能够防止发送端向接收端过多发送数据,可是发送端和接收端在链接创建之初,并不知道可用带宽是多少,所以须要一个估算机制,而后还能够根据网络中不断变化的条件而动态改变速度。
拥塞控制:防止过多的数据注入到网络中,这样可使网络中的路由器或链路不致于过载。
慢启动是实现拥塞控制的一种方法,此外还有拥塞预防、快速重发和快速恢复。
慢启动,便是在分组被肯定之后,增大窗口大小,慢慢启动。
具体实现以下:
发送方经过 TCP 链接初始化并维护一个拥塞窗口变量(cwnd)。并规定发送端与接收端之间最大能够传输的数据量为接收窗口(rwnd)与拥塞窗口(rwnd)的最小值。
cwnd 最初的值只有一个 TCP 段,1999年提高至 4 个 TCP 段,2013年,提高至 10 个 TCP 段。
因为慢启动的设计,限制了可用的吞吐量。对于大型流式下载服务的影响倒不显著,可是对于小文件的传输却很是不利,经常会出现尚未达到最大窗口请求就被终止的状况。
简单演示三次握手与慢启动对简单 HTTP 传输的影响。
链接参数:
当再次发送相同请求时:
慢启用使用 cwnd 做为起始值发送数据量,随后成倍增加。直到超过接收系统配置的拥塞阈值(ssthresh)窗口,或者发生分组丢失现象,此时拥塞预防算法介入。
因为已经发生拥堵,必须采起删包措施。须要从新调整 cwnd 大小,此后拥塞预防按照本身的算法来增大 cwnd 以免丢包。若再次丢包,则从头开始。