为什么您需要将您的服务器放置在地理上靠近您的用户的位置?其中一个原因是为了实现更低的延迟。当您发送应该尽快传送的短突发数据时,这很有意义。但是如果是大文件,比如视频呢?当然,接收第一个字节会有延迟损失,但之后不应该一帆风顺吗?
与HTTP一样,通过TCP发送数据时的一个常见误解是带宽与延迟无关。但是,对于TCP,带宽是延迟和时间的函数。让我们看看怎么做。
在客户端可以开始向服务器发送数据之前,它需要对TCP和TLS分别执行一次握手和另一次握手。
发送方挑选随机生成的序列号“x”,并将SYN分组发送给接收方。
接收器递增“x”,选择随机生成的序列号“y”,并发回SYN/ACK分组。
发送方递增序列号,并使用ACK数据包和应用程序数据的第一个字节进行回复。
TCP使用序列号来确保数据按顺序无漏洞地传输。
握手引入了完全往返,这取决于底层网络的延迟。TLS握手还需要最多两次往返。在TLS连接打开之前,不能发送任何应用程序数据,这意味着在此之前,您的带宽实际上为零。往返时间越短,建立连接的速度就越快。
流量控制是一种退避机制,用于防止发送方压倒接收方。
接收器将等待应用程序处理的传入TCP分组存储到接收缓冲器中。
每当接收方确认数据包时,它还会将缓冲区的大小传回发送方。如果发送方遵守协议,则会避免发送更多可以放入接收方缓冲区的数据。
此机制与应用程序级别的速率限制没有太大不同。但是,TCP不是对API密钥或IP地址进行速率限制,而是对连接级别进行速率限制。
发送方和接收方之间的往返时间(RTT)越短,发送方调整其输出带宽以适应接收方容量的速度就越快。
TCP不仅防止使接收方不堪重负,而且还防止淹没底层网络。
发送方如何知道底层网络的可用带宽是多少?估计它的唯一方法是通过测量进行实证。
这个想法是发送者维护一个所谓的“拥塞窗口”。该窗口表示无需等待对方确认即可发送的未完成数据包的总数。接收器窗口的大小限制拥塞窗口的最大大小。拥塞窗口越小,在任何给定时间可以传输的字节就越少,并且使用的带宽就越少。
当建立新连接时,拥塞窗口的大小被设置为系统默认值。然后,对于每个确认的数据包,窗口以指数方式增加其大小。这意味着我们不能在连接建立后立即使用网络的全部容量。同样,往返时间越短,发送方开始利用底层网络带宽的速度就越快。
如果数据包丢失,会发生什么情况?当发送器通过超时检测到丢失的确认时,称为“拥塞避免”的机制开始起作用,并且拥塞窗口大小被减小。从那时起,时间会使窗口大小增加一定的量,而超时则会使窗口的大小减少另一个量。
如前所述,拥塞窗口的大小定义了无需等待确认即可发送的最大位数。发件人需要等待完整的往返行程才能得到确认。因此,通过将拥塞窗口大小除以往返时间,我们得到最大理论带宽:
B a n d w i d t h=W i n S i z e R T带宽=\frac{WinSize}{rtt}B a n d w i d t h=R T T W I n S I z e这个简单的公式表明带宽是延迟的函数。TCP将非常努力地优化窗口大小,因为它对往返时间无能为力。但是,这并不总是产生最佳配置。
总之,拥塞控制是一种用于推断网络底层带宽和拥塞的自适应机制。类似的模式也可以应用于应用程序级别。想想当你在Netflix上看电影时会发生什么。它开始模糊;然后,它稳定在合理的水平,直到出现打嗝,质量再次恶化。应用于视频流的这种机制称为自适应比特率流。
如果您使用的是HTTP,那么您将受到底层协议的支配。如果你不知道香肠是怎么做的,你就不会得到最好的表现。
突发请求会受到冷启动处罚。可能需要多次往返才能通过TCP和TLS握手发送第一个字节。由于拥塞控制的工作方式,往返时间越短,底层网络的带宽利用率就越高。
整本书都是关于这个主题的,你可以做很多事情来挤压每一盎司的带宽。但是,如果您必须记住关于TCP的一件事,那么就让它这样吧:
您不能以比光速更快的速度发送数据,但您可以做的是将服务器放在离客户端更近的地方,并重复使用连接以避免冷启动带来的损失。
如果您想了解有关网络如何影响分布式系统的更多信息,请查看我即将到来的视频课程。