深入学习HTTP连接

105次阅读
没有评论

共计 2401 个字符,预计需要花费 7 分钟才能阅读完成。

什么是 HTTP 协议?

HTTP 协议是可靠的数据传输无状态协议,它属于应用层。HTTP 把联网的细节都交给了通用、可靠的因特网传输协议 TCP/IP。
只要建立了 TCP 连接,客户端和服务端之间的报文交换就不会丢失、不会被破坏。

为什么说 HTTP 是无状态的?

无状态的意思就是说每一次请求都与之前的请求无关,每一次请求包含的 cookie、url、首部等有状态的数据都是一个完整的文档,不需要请求其上下文。
缺点就是每一次请求都需要重新发送状态,也就是说服务器不会主动保存之前的状态。一般如果想让应用有状态,会在 http 协议中加上 cookie、session 等缓存机制。

HTTP 连接

在 HTTP 客户端向服务器发送报文之前,需要用 IP 地址和端口号在客户端和服务器之间建立一条 TCP/IP 连接。一般浏览器通过 HTTP 获取服务器中某个 HTML 资源过程如下:

  • 浏览器从 URL 中解析出服务器的主机名;
  • 浏览器通过 DNS 将主机名转换成服务器的 IP 地址;
  • 浏览器将端口号 (默认 80) 从 URL 中解析出来;
  • 浏览器建立一条与 Web 服务器的 TCP 连接;
  • 浏览器向服务器发送一条 HTTP 请求报文;
  • 服务器向浏览器回送一条 HTTP 响应报文;
  • 关闭连接,浏览器渲染文档并显示;

当然上述只是简单的描述,其中还有很多具体的步骤我们以后再说。

TCP 连接

我们知道,HTTP 协议依赖 TCP/IP 来进行通信。那么什么是 TCP/IP 呢?TCP/IP 是全球计算机网络都在使用的一种常用的分组交换网络分层协议集。

TCP 数据传输

  • TCP 为 HTTP 提供了一条可靠的比特传输管道。从 TCP 连接一端填入的字节会从另一端以原有的顺序正确地传送出来。
  • 传输的数据是通过称为 IP 分组的小数据块来发送的。每个 IP 分组都包括:

    • 一个 IP 分组首部(通常为 20 字节);
    • 一个 TCP 段首部(通常为 20 字节);
    • 一个 TCP 数据块(0 个或多个字节);
      ip 分组
  • TCP 连接通过 4 个值来识别:< 源 IP 地址、源端口号、目的 IP 地址、目的端口号 >,这 4 个值一起唯一地定义了一条连接。

TCP 性能考虑

  • HTTP 事务的时延:一般影响 HTTP 事务的时延主要有以下几点原因:

    1. 解析主机名:首次解析主机名需要通过 DNS 解析系统将 URI 中的主机名转换成一个 IP 地址,这可能要花费不少时间; 如果没有缓存 DNS,则以后的每次访问都需要重新解析 DNS,带来巨大时间消耗。
    2. 发送 TCP 连接请求:每条新的 TCP 连接都会有连接建立时延,如果同时发送上百条连接,则所耗时间大大增加。
    3. 连接建立完后,客户端会通过新建立的 TCP 管道发送 HTTP 请求报文,服务器接收到报文后会对请求进行处理。这其中传输报文、处理报文都需要花费时间; 服务器处理完报文后回送响应报文也需要传输时间
      总的来说,硬件速度、客户端和服务器的负载量、客户端与服务器之间的距离、报文的大小等会对时延产生巨大影响。
  • TCP 握手时延:TCP 连接需要经过三次握手,一般步骤如下:

    1. 请求新的 TCP 连接,客户端向服务器发送一个 TCP 分组(通常 40~60 字节)。分组中设置了一个特殊的 SYN 标记,说明是连接请求。
    2. 服务器接受连接,对连接参数进行计算,向客户端回送一个 TCP 分组,分组中的 SYN 和 ACK 标记都被置位,告诉客户端请求已接受。
    3. 客户端向服务器回送一条确认信息的 TCP 分组,包含 ACK 标记,告诉服务器连接已成功建立。(现代的 TCP 栈允许客户端在这个确认分组中发送数据)
  • TCP 延迟确认:TCP 有自己的确认机制来确保数据成功传输。每个 TCP 段都有一个序列号和数据完整性校验和。一般确认报文很小,所以 TCP 允许将确认报文和输出的数据分组组合在一起传输,这里就引入了一个“延迟确认”算法。“延迟确认”算法会在一个特定的窗口时间(通常 100~200ms)内将输出确认存放在缓存区,以寻找能携带它的输出数据分组,如果在特定时间内没有输出数据分组,就将确认信息放在单独的分组进行传输。但这样一般会引入比较大的时延,所以不一定完全要用延迟算法。
  • TCP 慢启动 :为了防止网络负载过大和阻塞,TCP 连接会采取慢启动,也就是说一开始限制连接的最大速度,随着数据的传输成功,慢慢增大传输速度。例如建立一个新连接,先发送一个分组,等确认成功后,才可以发送两个分组,等都被确认后,就可以发送四个分组,以此类推。。。
    由于这种特性,新连接的传输速度会比已经交换过一定量数据的、“已调谐”连接慢一些。
  • Nagle 算法问题:由于 TCP 允许将任意尺寸数据放入 TCP 栈中传输,所以如果 TCP 发送了大量包含少量数据的分组,则网络性能就会很低,浪费很多流量。Nagle 算法就是用来解决此类问题。该算法试图在发送一个分组之前,将大量 TCP 数据绑定在一起来提高网络效率。
    Nagle 算法希望发送全尺寸(LAN 上最大尺寸的分组大约 1500 字节,Internet 上是几百字节)的段。如果其他分组任然在传输过程中,就将那部分数据缓存起来,只有当挂起分组被确认,或者缓存中积累了足够发送一个全尺寸的分组后才将缓存的数据传输出去。这样就会带来性能问题,如果 HTTP 报文很小,一直达不到全尺寸,就会一直在等待那些永远不会到来的数据而引起时延; 而且 Nagle 算法会阻止数据传输直到有确认分组抵达,但确认分组自身又有延迟。

所以 HTTP 应用程序可以通过设置参数 TCP_NODELAY 来禁用 Nagle 算法,但是这样要确保会向 TCP 写入大块数据,而避免传输数量多的小分组。

  • TIME_WAIT、端口耗尽:TCP 关闭某个连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的 IP 地址和端口号,通常维持 2MSL(2 分钟)左右。这样可以防止在两分钟内创建、关闭并重新创建两个具有相同 IP 地址和端口号的连接。但这样就会限制可用端口号的数量,降低连接率。要确保不会遇到 TIME_WAIT 端口耗尽问题,可以增加客户端负载生成机器的数量,或者确保客户端和服务器在循环使用几个虚拟 IP 地址以增加更多的连接组合。
正文完
 
西蒙
版权声明:本站原创文章,由 西蒙 2017-04-04发表,共计2401字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码