WPO(Web Performance Optimization,Web 性能优化)
 
 
Web 性能优化
 
 
什么是延迟?
分组从信息源发送到目的地所需的时间。
 
什么是带宽?
逻辑或物理通信路径最大的吞吐量。
 
 
性能提升的意义,小案例:
为减少跨大西洋的延迟而铺设 Hibernia Express 专线
在金融市场上,很多常用交易算法首要的考虑因素就是延迟,因为几 ms 的差距可
能导致数百万美元的收益或损失。
2011 年初,华为与 Hibernia Atlantic 开始合作铺设一条横跨大西洋,连接伦敦和 纽约的近 5000 km 的海底光缆(Hibernia Express)。铺设这条海底光缆的唯一目 的,就是减少城市间的路由,(相对于使用其他横跨大西洋的线路)为交易商节 省 5 ms 的延迟。开通运营后,这条光缆将只由金融机构使用,耗资预计达 4 亿 美元。
简单计算一下,不难得出节省 1 ms 的成本是 8000 万美元。延迟的代价由此可见 一斑。
 
 
 
客户端到服务器的总延迟时间 包括:
• 传播延迟 消息从发送端到接收端需要的时间,是信号传播距离和速度的函数
• 传输延迟 把消息中的所有比特转移到链路中需要的时间,是消息长度和链路速率的函数
• 处理延迟 处理分组首部、检查位错误及确定分组目标所需的时间
• 排队延迟 到来的分组排队等待处理的时间
 
 
分组交换是什么?
分组交换技术(Packet switching technology)也称包交换技术,是将用户传送的数据划分成一定的长度,每个部分叫做一个分组,通过传输分组的方式传输信息的一种技术。它是通过计算机和终端实现计算机与计算机之间的通信,在传输线路质量不高、网络技术手段还较单一的情况下,应运而生的一种交换技术。每个分组的前面有一个分组头,用以指明该分组发往何地址,然后由交换机根据每个分组的地址标志,将他们转发至目的地,这一过程称为分组交换
 
 
什么是排队延迟?
分组到达路由器后,路由器必须检测分组的首部,以确定出站路由,并且还可 能对数据进行检查,这些都要花时间。由于这些检查通常由硬件完成,因此相应的 延迟一般非常短,但再短也还是存在。最后,如果分组到达的速度超过了路由器的 处理能力,那么分组就要在入站缓冲区排队。数据在缓冲区排队等待的时间,当然 就是排队延迟。
 
 
每个分组在通过网络时都会遇到这样或那样的延迟。发送端与接收端的距离越远, 传播时间就越长。一路上经过的路由器越多,每个分组的处理和传输延迟就越多。 最后,网络流量越拥挤,分组在入站缓冲区中被延迟的可能性就越大。
 
 
 
什么是本地路由器的缓冲区爆满 ?
缓冲区爆满(Bufferbloat)是 Jim Gettys 在 2010 年发明的一个术语,是排队延迟 影响网络整体性能的一个形象的说法。
造成这个问题的原因主要是如今市面上的路由器都会配备很大的入站缓冲区,以便 “不惜一切代价”避免丢包(分组)。可是,这种做法破坏了 TCP 的拥塞预防机制 (congestion avoidance),导致网络中产生较长且可变的延迟时间。
 
 
 
传输速度
光速极快,每秒能达到 299 792 458 米(大约 30 万公里),这是光在真空中的传播速度。
而网络中的分组是通过铜线、光纤等介 质传播的,这些介质会导致传播速度变慢。
光速与分组在介质中传播速度之比,叫 做该介质的折射率。这个值越大,光在该介质中传播的速度就越慢。
传播分组的光纤,大多数折射率从 1.4 到 1.6 不等。不过,我们也在逐渐改进传播 材料的质量,从而不断降低折射率。
为简单起见,我们大都假定光通过光纤的速度 约为每秒 200 000 000 米,对应的折射率约为 1.5。
 
 
 
内容分发网络
CDN(Content Delivery Network,内容分发网络)服务的用途很多,但最 重要的就是通过把内容部署在全球各地,让用户从最近的服务器加载内容, 大幅降低传播分组的时间。
 或许我们不能让数据传输得更快,但我们可以缩短服务器与用户之间的距 离!把数据托管到 CDN 能够显著提高性能。
 
 
ISP
互联网服务提供商(Internet Service Provider),简称ISP,指的是面向公众提供下列信息服务的经营者:一是接入服务,即帮助用户接入Internet;二是导航服务,即帮助用户在Internet上找到所需要的信息;三是信息服务,即建立数据服务系统,收集、加工、存储信息,定期维护更新,并通过网络向用户提供信息内容服务。
 
 
 
使用 traceroute 测量延迟
traceroute 是一个简单的网络诊断工具,可以列出分组经过的路由节点,以及它在 IP 网络中每一跳的延迟。为找到每一跳的节点,它会向目标发送一系列分组,每 次发送时的“跳数限制”都会递增(1、2、3,等等)。在达到跳数限制时,中间 的节点会返回 ICMP Time Exceeded 消息,traceroute 根据这个消息可以计算出每 一跳的延迟。
在 Unix 平台上,可以在命令行运行 traceroute。而在 Windows 平台中,相应的 命令叫 tracert。
到 2010 年初,研究人员已经可以在每个信道中耦合 400 多种波长的光线,最大容 量可达 171 Gbit/s,而一条光纤的总带宽能够达到 70 Tbit/s !如此大的吞吐量如果 换成铜线(传输电信号)可能需要几千条。自然地,像两个大陆间的海底数据传输, 现在都已经使用光纤连接了。每条光缆会封装几条光纤(常见的是 4 条),折算出来 的带宽容量能达到每秒几百太比特。
 
 
 
因特网有两个核心协议 :
IP 和 TCP。
IP,即 Internet Protocol(因特网协议),负 责联网主机之间的路由选择和寻址;
TCP,即 Transmission Control Protocol(传输 控制协议),负责在不可靠的传输信道之上提供可靠的抽象层。
TCP/IP 也常被称为 “因特网协议套件”(Internet Protocol Suite),是由 Vint Cerf 和 Bob Khan 在他们 1974 的论文“A Protocol for Packet Network Intercommunication”(一种分组网络互 通的协议)中首次提出来的。
 
 
TCP 和 IP 协议的历史
我们都知道有 IPv4 和 IPv6,那 IPv1~3 和 IPv5 呢? IPv4 中的 4 表示 TCP/IP 协议的第 4 个版本,发布于 1981 年 9 月。最初的 TCP/IP 建议中同时包含两个协议,但标准草案 第 4 版将这两个协议分开,使之各自成为独立的 RFC。实际上,IPv4 中的 v4 只是表 明了它与 TCP 前 3 个版本的承继关系,之前并没有单独的 IPv1、IPv2 或 IPv3 协议。
1994 年,当工作组着手制定 Internet Protocol next generation(IPng)需要一个新版 本号时,v5 已经被分配给了另一个试验性协议 Internet Stream Protocol(ST)。但 ST 一直没有什么进展,这也是我们为什么很少听说它的原因。结果 TCP/IP 的下 一版本就成了 IPv6。
 
 
 
tcp的三次握手
Web 性能优化
• SYN
客户端选择一个随机序列号 x,并发送一个 SYN 分组,其中可能还包括其他 TCP 标志和选项。
• SYN ACK
服务器给 x 加 1,并选择自己的一个随机序列号 y,追加自己的标志和选项,然 后返回响应。
• ACK
客户端给 x 和 y 加 1 并发送握手期间的最后一个 ACK 分组。
三次握手完成后,客户端与服务器之间就可以通信了。
客户端可以在发送 ACK 分 组之后立即发送数据,而服务器必须等接收到 ACK 分组之后才能发送数据。
这个 启动通信的过程适用于所有 TCP 连接,因此对所有使用 TCP 的应用具有非常大的 性能影响,因为每次传输应用数据之前,都必须经历一次完整的往返。
 
 
TCP 快速打开技术
遗憾的是,连接并不是想重用就可以重用的。事实上,由于非常短的 TCP 连接在 互联网上随处可见,握手阶段已经成为影响网络总延迟的一个重要因素。为解决 这个问题,人们正在积极寻找各种方案,其中 TFO(TCP Fast Open,TCP 快速打 开)就是这样一种机制,它致力于减少新建 TCP 连接带来的性能损失。
经过流量分析和网络模拟,谷歌研究人员发现 TFO 平均可以降低 HTTP 事务网络 延迟 15%、整个页面加载时间 10% 以上。在某些延迟很长的情况下,降低幅度甚 至可达 40%。
Linux 3.7 及之后的内核已经在客户端和服务器中支持 TFO,因此成为了客户端和 服务器操作系统选型的有力候选方案。即便如此,TFO 并不能解决所有问题。它 虽然有助于减少三次握手的往返时间,但却只能在某些情况下有效。比如,随同 SYN 分组一起发送的数据净荷有最大尺寸限制、只能发送某些类型的 HTTP 请 求,以及由于依赖加密 cookie,只能应用于重复的连接。要了解有关 TFO 容量及 局限性的更多细节,请参考 IETF 最新的“TCP Fast Open”草案。
 
 
慢启动重启
除了调节新连接的传输速度,TCP 还实现了 SSR(Slow-Start Restart,慢启动重 启)机制。这种机制会在连接空闲一定时间后重置连接的拥塞窗口。道理很简单, 在连接空闲的同时,网络状况也可能发生了变化,为了避免拥塞,理应将拥塞窗 口重置回“安全的”默认值。
毫无疑问,SSR 对于那些会出现突发空闲的长周期 TCP 连接(比如 HTTP 的 keep-alive 连接)有很大的影响。因此,我们建议在服务器上禁用 SSR。在 Linux 平台,可以通过如下命令来检查和禁用 SSR:
• $> sysctl net.ipv4.tcp_slow_start_after_idle
• $> sysctl -w net.ipv4.tcp_slow_start_after_idle=0
 
 
慢启动
1988 年,Van Jacobson 和 Michael J. Karels 撰文描述了 解决网络拥塞崩溃 的几种算法: 慢启动、拥塞预防、快速重发和快速恢复。
这 4 种算法很快被写进了 TCP 规范。事 实上,正是由于这几种算法加入 TCP,才让因特网在 20 世纪 80 年代末到 90 年代 初流量暴增时免于大崩溃。
慢启动即在分组被确认后增大窗口大小,慢慢地启动!最初,cwnd 的值只有 1 个 TCP 段。1999 年 4 月,RFC 2581 将其增加到了 4 个 TCP 段。2013 年 4 月,RFC 6928 再次将其提高到 10 个 TCP 段。
新 TCP 连接传输的最大数据量取 rwnd 和 cwnd 中的最小值,而服务器实际上可以 向客户端发送 4 个 TCP 段,然后就必须停下来等待确认。此后,每收到一个 ACK, 慢启动算法就会告诉服务器可以将它的 cwnd 窗口增加 1 个 TCP 段。每次收到 ACK 后,都可以多发送两个新的分组。TCP 连接的这个阶段通常被称为“指数增长”阶 段(图 2-3),因为客户端和服务器都在向两者之间网络路径的有效带宽迅速靠拢。
Web 性能优化
为什么知道有个慢启动对我们构建浏览器应用这么重要呢?因为包括 HTTP 在内的 很多应用层协议都运行在 TCP 之上,无论带宽多大,每个 TCP 连接都必须经过慢 启动阶段。换句话说,我们不可能一上来就完全利用连接的最大带宽!
相反,我们要从一个相对较小的拥塞窗口开始,每次往返都令其翻倍(指数式增 长)。而达到某个目标吞吐量所需的时间,就是客户端与服务器之间的往返时间和初 始拥塞窗口大小的函数
 
 
TCP 的队首(HOL,Head of Line)阻塞
每个 TCP 分组都会带着一个唯一的序列号被发出,而 所有分组必须按顺序传送到接收端。如果中途有一个分组没能到达接收 端,那么后续分组必须保存在接收端的 TCP 缓冲区,等待丢失的分组重发并到达接 收端。这一切都发生在 TCP 层,应用程序对 TCP 重发和缓冲区中排队的分组一无所 知,必须等待分组全部到达才能访问数据。在此之前,应用程序只能在通过套接字 读数据时感觉到延迟交付。
Web 性能优化
队首阻塞造成的延迟可以让我们的应用程序不用关心分组重排和重组,从而让代码 保持简洁。然而,代码简洁也要付出代价,那就是分组到达时间会存在无法预知的 延迟变化。这个时间变化通常被称为抖动,也是影响应用程序性能的一个主要因素。
另外,有些应用程序可能并不需要可靠的交付或者不需要按顺序交付。比如,每个 分组都是独立的消息,那么按顺序交付就没有任何必要。而且,如果每个消息都会 覆盖之前的消息,那么可靠交付同样也没有必要了。可惜的是,TCP 不支持这种情况,所有分组必须按顺序交付。 无需按序交付数据或能够处理分组丢失的应用程序,以及对延迟或抖动要求很高的
应用程序,最好选择 UDP 等协议。
 
 
 
 
优化配置自己的服务器
• 增大TCP的初始拥塞窗口
加大起始拥塞窗口可以让 TCP 在第一次往返就传输较多数据,而随后的速度提 升也会很明显。对于突发性的短暂连接,这也是特别关键的一个优化。
• 慢启动重启
在连接空闲时禁用慢启动可以改善瞬时发送数据的长 TCP 连接的性能。
• 窗口缩放(RFC 1323) 启用窗口缩放可以增大最大接收窗口大小,可以让高延迟的连接达到更好吞 吐量。
• TCP快速打开
在某些条件下,允许在第一个 SYN 分组中发送应用程序数据。TFO(TCP Fast Open,TCP 快速打开)是一种新的优化选项,需要客户端和服务器共同支持。 为此,首先要搞清楚你的应用程序是否可以利用这个特性。
 
 
 
 
影响tcp性能的因素
  • TCP 三次握手增加了整整一次往返时间;
  • TCP 慢启动将被应用到每个新连接;
  • TCP 流量及拥塞控制会影响所有连接的吞吐量;
  • TCP 的吞吐量由当前拥塞窗口大小控制。
 
 
 
 
服务器性能检查清单
  • 把服务器内核升级到最新版本(Linux:3.2+);
  • 确保 cwnd 大小为 10;
  • 禁用空闲后的慢启动;
  • 确保启动窗口缩放;
  • 减少传输冗余数据;
  • 压缩要传输的数据;
  • 把服务器放到离用户近的地方以减少往返时间;
  • 尽最大可能重用已经建立的 TCP 连接。
 
 
 
 
数据报(datagram)和分组(packet)
数据报(datagram)和分组(packet)是两个经常被人混用的词,实际上它们还是 有区别的。分组可以用来指代任何格式化的数据块,而数据报则通常只用来描述那 些通过不可靠的服务传输的分组,既不保证送达,也不发送失败通知。正因为如此, 很多场合下人们都把 UDP 中 User(用户)的 U,改成 Unreliable(不可靠)的 U, 于是 UDP 就成了“不可靠数据报协议”(Unreliable Datagram Protocol)。这也是为 什么把 UDP 分组称为数据报更为恰当的原因。
 
 
 
 
udp的应用
关于 UDP 的应用,最广为人知同时也是所有浏览器和因特网应用都赖以运作的,就 是 DNS(Domain Name System,域名系统)。DNS 负责把对人类友好的主机名转换 成 IP 地址。可是,尽管浏览器有赖于 UDP,但这个协议以前从未被看成网页和应 用的关键传输机制。HTTP 并未规定要使用 TCP,但现实中所有 HTTP 实现(以及 构建于其上的所有服务)都使用 TCP。
 
 
 
IP 层的主要任务就是按照地址从源主机向目标主机发送数据报。为此,消息会被封 装在一个 IP 分组内(如下图),其中载明了源地址和目标地址,以及其他一些路由参 数。注意,数据报这个词暗示了一个重要的信息:IP 层不保证消息可靠的交付,也 不发送失败通知,实际上是把底层网络的不可靠性直接暴露给了上一层。如果某个 路由节点因为网络拥塞、负载过高或其他原因而删除了 IP 分组,那么在必要的情况 下,IP 的上一层协议要负责检测、恢复和重发数据。
IPv4 首部(20 字节)
Web 性能优化
UDP 协议会用自己的分组结构(图 3-2)封装用户消息,它只增加了 4 个字段:源 端口、目标端口、分组长度和校验和。这样,当 IP 把分组送达目标主机时,该主机 能够拆开 UDP 分组,根据目标端口找到目标应用程序,然后再把消息发送过去。仅 此而已。
UDP 首部(8 字节)
Web 性能优化
事实上,UDP 数据报中的源端口和校验和字段都是可选的。IP 分组的首部也有校验 和,应用程序可以忽略 UDP 校验和。也就是说,所有错误检测和错误纠正工作都可 以委托给上层的应用程序。说到底,UDP 仅仅是在 IP 层之上通过嵌入应用程序的 源端口和目标端口,提供了一个“应用程序多路复用”机制。明白了这一点,就可 以总结一下 UDP 的无服务是怎么回事了。
• 不保证消息交付 不确认,不重传,无超时。
• 不保证交付顺序 不设置包序号,不重排,不会发生队首阻塞。
• 不跟踪连接状态 不必建立连接或重启状态机。
• 不需要拥塞控制 不内置客户端或网络反馈机制。
TCP 是一个面向字节流的协议,能够以多个分组形式发送应用程序消息,且对分组 中的消息范围没有任何明确限制。因此,连接的两端存在一个连接状态,每个分组 都有序号,丢失还要重发,并且要按顺序交付。相对来说,UDP 数据报有明确的限 制:数据报必须封装在 IP 分组中,应用程序必须读取完整的消息。换句话说,数据 报不能分片。
UDP 是一个简单、无状态的协议,适合作为其他上层应用协议的辅助。实际上,这 个协议的所有决定都需要由上层的应用程序作出。不过,在急着去实现一个协议来 扮演 TCP 的角色之前,你还应该认真想一想这里涉及的复杂细节,比如 UDP 要与 很多中间设备打交道(NAT 穿透),再想一想设计网络协议的那些最佳实践。如果 没有周密的设计和规划,一流的构想也可能沦为二流的 TCP 实现。TCP 中的算法和 状态机已经经过了几十年的磨合与改进,而且吸收几十种并不那么容易重新实现的 机制。
 
 
 
UDP与网络地址转换器
令人遗憾的是,IPv4 地址只有 32 位长,因而最多只能提供 42.9 亿个唯一 IP 地址。 1990 年代初,互联网上的主机数量呈指数级增长,但不可能所有主机都分配一个唯 一的 IP 地址。1994 年,作为解决 IPv4 地址即将耗尽的一个临时性方案,IP 网络地 址转换器(NAT,Network Address Translator)规范出台了,这就是 RFC 1631。
建议的 IP 重用方案就是在网络边缘加入 NAT 设备,每个 NAT 设备负责维护一个 表,表中包含本地 IP 和端口到全球唯一(外网)IP 和端口的映射。这样, NAT 设备背后的 IP 地址空间就可以在各种不同的网络中得到重用,从而解决地址 耗尽问题。
IP网络地址转换器
Web 性能优化

相关文章: