延迟与带宽
网站越快,用户黏性越高;
网站越快,用户忠诚度越高;
网站越快,用户转化率越高。
决定网络通信的两个方面:延迟与带宽。
- 延迟: 分组从信息源发送到目的地所需的时间。
- 带宽:逻辑或物理通信路径最大的吞吐量。
目标: 低延迟,高带宽
延迟
延迟是消息
或分组
从起点到终点经历的时间。
影响延迟的因素:
- 传播延迟
消息从发送端到接收端需要的时间,与信号传播距离和速度有关。
- 传输延迟
把消息中的所有比特转移到链路中需要的时间,与消息长度和链路速率有关。
- 处理延迟
处理分组首部、检查位错误及确定分组目标所需的时间。
- 排队延迟
到来的分组排队等待处理的时间。
以上延迟的时间总和,就是客户端到服务器的总延迟时间。
CDN
CDN(Content Delivery Network,内容分发网络)主要就是把内容部署到全球各地,让用户从最近的服务器加载内容,大幅降低传播分组的时间。
使用traceroute
测量延迟
traceroute是一个简单的网络诊断工具,可以列出分组经过的路由节点,以及他在IP网络中的每一跳延迟。在windows系统中可以使用tracert
来测试。
当ICMP协议被禁用的时候,可以采用 lft, paketto, hping, superping.d , NetPerf, IPerf
TCP
TCP协议
传输控制协议,即Transmission Control Protocol,缩写为TCP,是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。TCP协议位于IP协议之上,应用层之下的传输层。
TCP连接包括了三种状态: 连接创建、数据传送和连接终止。操作系统将TCP连接抽象为套接字的编程接口给程序使用,并且要经历一系列的状态改变。
创建通路
所有的TCP连接要通过三次握手,客户端与服务器在交换应用数据之前,必须就起始分组序列号,以及其他的一些连接相关的细节达成一致。序列号由两端随机生成。
- SYN
客户端选择一个随机序列号X,并发送一个SYN分组,其中可能包括其他TCP标识和选项。
- SYN ACK
服务器给X加1,并选择自己的一个随机序列号Y,追加自己的标志和选项,然后返回响应。
- ACK
客户端给X和Y加1并发送握手期间的最后一个ACK分组。
三次握手完成后,客户端与服务器就可以通信了。客户端在发送ACK分组后就可以立即发送数据,服务器则必须等待接收到ACK分组后才能够发送数据。
三次握手带来的延迟使得每次创建一个新TCP连接都要付出巨大代价,所以这里是提升TCP应用性能的关键。
TCP Fast Open 是减少新建TCP连接带来性能损失的一种机制。通过握手开始时的 SYN 包中的 TFO cookie(一个 TCP 选用项)来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的 ACK 包收到之前就开始发送数据,这样便跳过了一个绕路的行为,更在传输开始时就降低了延迟。
拥塞预防及控制
- 流量控制
流量控制是一种预防发送端过多向接收端发送数据的机制。为了实现流量控制,TCP连接的每一方都要通告自己的接收窗口(rwnd),其中包含能够保存数据的缓冲区空间大小信息。
第一次建立连接时,发送端和接收端都会使用窗口默认设置来发送
rwnd
。在浏览器网页时,需要从服务器向浏览器下载数据,所以此时客户端的窗口成为瓶颈。而在上传图片等数据时,服务器的接收窗口成为了瓶颈。在传输过程中,其中一端跟不上数据传输,此时它可以向发送端通告一个较小的窗口。假设窗口为0,则意味着必须有应用层先清空缓冲区,才能够接受剩余数据。
每个ACK分组都会携带相应的最新的rwnd值,以便于两端动态调整数据流速,使之适应发送端和接收端的容量和处理能力。
在Linux操作系统中,可以通过以下命令检查TCP窗口缩放机制。
- 拥塞控制
发送端、接收端在连接建立之初,无法预测双方的网络带宽,因此需要一个估算机制,然后还需要根据网络中不断变化的条件动态改变速度。
1988年,Van Jacobson和Michael J. Karels撰文描述了解决这种问题的方法:慢启动、拥塞预防、快速重发和快速恢复。
- 拥塞预防
TCP调节性能依赖于丢包反馈机制。拥塞预防算法把丢包作为网络拥塞的标志,即路径中某个连接或者路由器已经拥堵,以至于必须采取删包策略。因此,需要调整窗口大小,以避免更多的包丢失,保证网络畅通。重置拥塞窗口后,拥塞预防机制按照自己的算法来增大窗口以及尽量避免丢包。
- 慢启动
新的TCP链接最大数据量取决于RWND和CWND的最小值。慢启动导致了客户端与服务器之间经过几百毫秒才能够达到接近最大速度的问题,对于大型流式下载服务影响不显著,但对于大多数的HTTP连接,特别是一些短暂、突发的连接,常常会出现还没达到最大窗口请求就被终止的情况,很多Web性能受到服务器与客户端之间往返时间的制约。慢启动限制了可用的吞吐量,对于小文件传输十分不利。
- 拥塞预防
- 带宽延迟积
带宽延迟积(Bandwidth-delay product),数据链路的容量与其端到端延迟的乘积。这个结果就是任意时刻处于在途未确认状态的最大数据量。
发送端和接收端指甲的在途未确认的最大数据量,取决于拥塞窗口和接收窗口的最小值。接收窗口会随着每次的ACK一起发送,拥塞窗口则由发送端根据拥塞控制和预防算法动态调整。当接收或发送的数据超过了未确认的最大数据量,都必须停下来等待另一方的ACK来确认某些分组才能够继续。等待的时间取决于往返时间。
为了获得最大的吞吐量,应该让窗口足够大,以保证任何一段能在ACK返回前持续发送数据。只有传输不间断,才能够保证最大的吞吐量。
- 流量控制窗口和拥塞控制窗口多大才合适呢?假设cwnd和rwnd的最小值为16KB,往返时间为100ms:
不论接受或发送的实际带宽,TCP连接的数据传输率都不会超过1.31Mbit/s。
- 如果往返时间不变,发送端的带宽为10Mbit/s,接收端为100Mbit/s+,且两端之间没有网络拥塞。那么窗口应该是多大呢?
窗口至少要122.1KB才能够充分利用10Mbit/s带宽。但在RFC 1323中,TCP接受窗口最大只有64KB。所以,尽管窗口大小会自动调节,但也仍旧是TCP性能限制因素。
BDP是往返时间和目标传输速度的函数,因此往返时间不仅是高传输延迟中的瓶颈,也是LAN中的瓶颈。
- 流量控制窗口和拥塞控制窗口多大才合适呢?假设cwnd和rwnd的最小值为16KB,往返时间为100ms:
- 队首阻塞
每个TCP分组都会带着唯一的序列号被发出,而所有分组必须按照传输顺序传送到接收端。如果中途有一个分组没能到到接收端,而后续分组必须保存在接收端的TCP缓冲区里,等待丢失的分组重发并到达接收端。这些情况都发生在TCP层,应用程序对TCP重发和缓冲区排队的分组一无所知,必须等待分组全部到达才能够访问。在此之前,应用程序只能通过套接字读数据时感觉延迟交付。这种效应成为TCP的队首阻塞。
队首阻塞造成的延迟可以让程序不必关心分组重排和重组的事情,从而使得我们的代码更加简洁。但是,分组到达时间存在无法预知的延迟变化。这个时间变化通常被称为抖动。对延迟或者抖动要求高或者无需按序交付数据、能够自行处理分组丢失的应用程序可以选用UDP。
丢包是TCP达到最佳性能的关键,被删除的包是一种反馈机制,能够让接收端和发送端各自调整速度,以免网络拥堵,同时保持延迟最短(缓冲区爆满问题)。
针对TCP优化意见
优化目标: 最大吞吐量 最小延迟
TCP是一个自适应、对所有网络节点一视同仁的、最大限制利用底层的网络协议。
优化TCP的最佳路径就是调整它感知当前网络状况的方式,根据它之上或之下的抽象层类型和需求来改变他的行为。
TCP的核心原理和影响是不变的:
- TCP三次握手增加了整整一次的往返时间;
- TCP慢启动被应用到每一次的新连接;
- TCP流量及拥塞控制会影响所有连接的吞吐量。
- TCP的吞吐量由当前拥塞窗口大小确定。
现代高速网络中的TCP连接的数据传输速度受到接收端和发送端的往返时间的限制。此外,延迟依旧受限于光速,而且已经限定在其最大值的一个很小的常数因子之内。所以,大多数情况下,TCP的瓶颈都是延迟,而非带宽。
服务器配置调优
- 增大TCP的初始拥塞窗口
加大拥塞窗口能够让TCP在第一次往返中就可以传输较多的数据,而随后的速度提升明显。对于突发性的短暂连接,这是一个很重要的优化的点。
- 慢启动重启
在连接空闲时禁用慢启动可以改善瞬时发送数据的长TCP连接的性能。
- 窗口缩放(RFC 1323)
启用窗口缩放可以增大最大接收窗口的大小,可以让高延迟的连接达到更好的吞吐量。
- TCP快速打开
在某些条件下,允许在第一个SYN分组中发送应用程序数据。不过需要发送端和客户端同时支持TFO(TCP快速打开)
在Linux系统中,可以使用ss
查看当前打开的套接字的各种统计信息。
ss --options --extended --memory --processes --info
可以查看到当前的通信节点以及他们相应的连接设置。
应用程序行为调优
- 消除不必要的数据传输,如不必要的资源下载后者通过压缩算法将传送的数据量降到最低;
- 实现数据的短距离传输,如采用CDN技术来减少网络往返的延迟,从而显著提升TCP的性能;
- 尽可能重用TCP连接,把慢启动和其他拥塞控制机制的影响降低到最小。
性能检查清单
- 把服务器内核升级到最新版(Linux 3.2+)
- 确保cwnd大小为10
- 禁用空闲后的慢启动
- 确保启动窗口的缩放
- 减少传输的冗余数据
- 压缩要传输的数据
- 把服务器放到离用户最近的地方减少往返时间
- 尽最大可能重用已经建立的TCP连接
来源
- 《Web性能权威指南》
- 《图解TCP/IP》