3.3、对TCP性能的考虑

HTTP 紧挨着 TCP,位于其上层,所以 HTTP 事务的性能在很大程度上取决于底层 TCP 通道的性能。

3.3.1、HTTP事务的时延

下图是串行HTTP事务的时间线,可以看到处理时间是比其他时间都短的,除非客户端或服务器超载,或正在处理复杂的动态资源, 否则 HTTP 时延就是由 TCP 网络时延构成的。

TCP时延

导致时延的主要原因:

  • DNS查询可能要花数十秒的时间。不过大部分HTTP 客户端都有一个小的 DNS 缓存,用来保存近期所访问站点的 IP 地址,这样子查询就可以立即完成。
  • 每条新的TCP连接时延,通常最多只有一两秒钟。但是有数百个HTTP事务则会增加时延了。
  • 传输报文、处理报文的时间。

TCP 网络时延的大小取决于硬件速度、网络和服务器的负载,请求和响应报文 的尺寸,以及客户端和服务器之间的距离,TCP 协议的技术复杂性。

3.3.2、性能聚焦

最常见的TCP相关时延:

  • TCP 连接建立握手;
  • 用于捎带确认的TCP延迟确认算法;
  • TCP慢启动拥塞控制;
  • 数据聚集的Nagle算法;
  • TIME_WAIT时延和端口耗尽。
(1) TCP连接的握手时延

小的HTTP事务可能会在TCP建立上花费 50%,或更多的时间。

握手步骤:

  • 请求新TCP连接时,发送一个40~60字节的TCP分组,分组中的SYN标记说明是请求连接。如下图的(a)步骤。
  • 服务器接收连接,计算连接参数,回送TCP分组,分组中SYN和ACK说明已接受请求。如下图的(b)步骤。
  • 客户端回送确认信息,通知成功建立,此信息可发送数据。如下图的(c)步骤。

握手时延

(2) 延迟确认

每个 TCP 段都有一个序列号和数据完整性校验和。

每个段的接收者收到完好的段 时,都会向发送者回送小的确认报文,TCP 允许在发往相同方向的输出数据分组中对其进行“捎 带”确认报文,更有效利用网络。

如果发送者没有在指定的窗口时间内收到确 认信息,发送者就认为分组已被破坏或损毁,并重发数据。

为了增加确认报文找到同向传输数据分组的可能性,很多 TCP 栈都实现了一种 “延迟确认”算法。 延迟确认算法会在一个特定的窗口时间(通常是 100 ~ 200 毫 秒)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组,寻找不了且超出时间则单独发送。

HTTP 具有双峰特征的请求 - 应答行为降低了捎带信息的可能,因此延迟确认算法会引入相当大的时 延。根据所使用操作系统的不同,可以调整或禁止延迟确认算法。

(3) TCP慢启动

TCP数据传输的性能还取决于 TCP 连接的使用期(age)。TCP 连接起初会限制连接的最大速度,如果数据成功传输,随着时间的推移提高传输的速度,这被称为TCP慢启动(slow start),用于防止因特网的突然过载和拥塞。

TCP 慢启动限制了一个 TCP 端点在任意时刻可以传输的分组数。

(4) Nagle算法与TCP_NODELAY

Nagle算法试图在发送一个分组之前,将大量 TCP数据绑定在一起,防止发送大量单字节分组的行为(发送端傻窗口综合症),以提高网络效率。 Nagle 算法鼓励发送全尺寸(LAN 上最大尺寸的分组大约是 1500 字节,因特网几百字节)的段。如果其他分组仍然在传输过程中,就将非全尺寸的数据缓存起来。只有当挂起分组被确认,或者缓存中积累了足够发送一个全尺寸分组的数据时,才会将缓存的数据发送出去。

Nagle 算法会引发几种 HTTP 性能问题:

  • 小的 HTTP 报文可能无法填满一个分组,可能会因为等待那些永远不会到来的额外数据而产生时延。
  • Nagle 算 法与延迟确认之间的交互存在问题:Nagle 算法会阻止数据的发送,直到有确认分组抵达为止,但确认分组自身会被延迟确认算法延迟 100 ~ 200 毫秒。

设置参数 TCP_NODELAY,禁用 Nagle 算法,提高性能,但是一定要确保向 TCP 写入大块的数据,这样才不会产生一堆小分组。

(5) TIME_WAIT累积与端口耗尽

当某个 TCP 端点关闭 TCP 连接时,会在内存中维护一个小的控制块,用来记录最 近所关闭连接的 IP 地址和端口号。这类信息维持的时间通常是最大分段使用期的两倍(称为 2MSL,通常为 2 分钟左右),防止在两分钟内 创建、关闭并重新创建两个具有相同 IP 地址和端口号的连接。

进行性能基准测试时,通常只有一台或几台用来产生流量的计算机连接到某 系统中去,这样就限制了连接到服务器的客户端 IP 地址数。用 TIME_W AIT 防止端口号重用时,这些 情况也限制了可用的连接值组合。

因为TCP 连接是由 4 个值来唯一定义一条连接的:< 源 IP 地址、源端口号、目的 IP 地址、目的端口号 > 源IP和端口号减少,其他不变的话,则导致TCP连接减少。

即使没有遇到端口耗尽问题,也要特别小心在有大量打开连接或控制块的情况 下,有些操作系统的速度会严重减缓