HTTP权威指南学习笔记(2)-TCP和HTTP连接管理

转载请注明出处 http://www.paraller.com
原文排版地址 点击获取更好阅读体验

核心知识点

  • HTTP协议 实际上是 TCP连接 + HTTP使用规则, 所以HTTP只是一个应用层协议.
  • TCP 为HTTP提供一条可靠的比特传输管道,按序无差错的传输。
  • HTTPS就是在 HTTP和TCP之间插入一个密码加密层
  • TCP是通过名为 IP分组(或IP数据报) 的小数据块来发送的
  • TCP是通过四个值来识别的 源IP地址、源端口号、目的IP地址、目的端口号;两条不同的TCP连接不能拥有完全相同是四个值

HTTP传输流程

  • 将报文数据通过流数据的形式,通过TCP传输
  • TCP收到数据流之后,将数据流分成小数据块,简称
  • 将段封装在IP分组中,通过因特网进行传输

IP分组的组成

  • IP分组首部(通常20字节): 源和目的IP地址、长度、和其他标记
  • TCP段首部(通常20字节): TCP端口号、TCP控制标记、用户数据排序和完整性检查的数字值
  • TCP段数据(0或更多): 流数据内容

套接字编程

套接字API允许创建TCP的端点数据结构,将这些端点与远程服务器的TCP端点进行通信,进行数据的读写,隐藏了握手细节,以及TCP数据流与IP分组之间的细节

HTTP事务的性能很大程度取决于TCP的性能,

HTTP事务的时延
一个完成的HTTP事务过程 : DNS查询 – 建立TCP连接 – 发起请求 – 事务处理 – 接收响应 – 关闭连接
其中事务处理的耗时是很短的(除非应用服务器过载)

性能聚焦区域:

常见的一些TCP相关时延

TCP连接建立握手

在建立新的TCP连接,甚至是在发送任意数据之前,TCP软件会交换一系列的IP分组, 对连接的有关参数进行沟通, 如果连接之传输少量的数据,这个交换过程会严重降低HTTP的性能。

三次握手机制:

  • 客户端会发送一个包含SYN标记的TCP分组给服务端,代表这个是连接请求
  • 服务端收到这个分组之后,会对连接参数进行计算,并回送一个带有 SYN和ACK标记的分组。代表请求已经被接受
  • 客户端回送服务器一个带有 ACK标记分组,通知服务器连接已经成功建立(现在的TCP栈可以在这个分组中发送数据)

通常HTTP事务的交换的数据不多,小的事务可能在TCP的建立上花费了50%的时间。

解决方案:

用于捎带确认的 TCP延迟确认算法

因特网无法确保数据传输中没有出错,TCP通过自身的机制来保证数据的正确传输:

  • 发送的每个TCP段都有一个数据完整性的校验值,TCP的一端接收到IP分组信息后,检验成功会回送一个确认分组,如果在指定时间内没有收到确认分组,另一端会重新发送TCP段。
  • 因为确认分组很小,所以TCP允许在回送的TCP段中捎带一份确认分组。提高效率

延迟确认算法:

  • 定义:为了提高确认分组找到同向的数据分组,会在一个特定的时间窗口内(100~200Ms),将确认分组放在缓冲池中,等同向的数据分组,如果在规定的时间内没有找到,将单独发送确认分组。
  • 弊端:如果没有那么多同向的数据分组回传,这个时间窗口就会造成性能低下,可以禁止或调整这个特性。
TCP慢启动拥塞控制

TCP的连接速度会随着传输时间自我调整,当TCP成功建立的时候,会限制发送速度;TCP会发送一组数据分组,确认没有问题之后一次发送两组数据,两组数据没有问题会发送四组数据,直到到达上限,所以长时间保持连接传输的TCP连接要比刚开始建立的连接拥有更快的传输速率。

解决方案:重用现存连接,HTTP持久连接。

面试题:HTTP持久连接的原因:TCP建立的50%耗时、传输速率

数据聚集的Nagle 算法

Nagle算法的思想是,每个IP分组至少40个字节,如果要发送的TCP段数据很小,过多的小数据分组会降低TCP性能,所以主张将小的TCP段集合在一个IP分组中发送;

鼓励发送全尺寸的段,因特网上一般是几百字节,如果TCP已经发送了一个全尺寸的段,剩下的数据有两种方式:

  • 等待上次发送的段确认分组到达之后发送
  • 等到填满了一个全尺寸的段再发送。

弊端:

  • 小的HTTP报文可能无法填满一个全尺寸段,这个时间窗口会造成延迟
  • 在等待上个数据的确认分组的时候,本身就存在延迟确认的时间窗口(100~200ms)

禁用Nagle算法的设置参数是TCP_NODELAY,但要确保你发送的数据都是大尺寸的。

TIME_WAIT 时延和端口耗尽
  • 当某个TCP端点关闭TCP连接的时候,会在内存中维持一个控制块的,用来记录最近连接的IP地址和端口号
  • 会维护一段时间,大概是两分钟(最大分段使用期的两倍),以前路由器速度很慢的时候,预估一个分组信息在因特网丢弃之前,它最多可以保存一分钟
  • 目的是防止两分钟内重新创建了相同地址端口的连接,A端发送给B端的分组信息,因为没有过期,并且是相同的TCP连接,导致数据被重复发送,破坏TCP数据。

实际场景:

  • HTTP服务器在80端口上进行监听,根据格式 <source-IP, source-Port , des-IP , 80>,地址是固定的,只有 source-Port是可以改变的
  • 客户端每次连接,为了连接的唯一性,都会获取一个端口号,假设source主机端口号只有60000个, 那么每秒的连接数就被限制在 60000/120=500个

HTTP连接管理

Connection首部:指定了连接的一些元数据;HTTP应用程序在接到带有Connection首部的报文时,会解析这些值并应用,然后在转发到下一个应用程序之前会删除Connection信息。

提高HTTP性能的几种方式:

  • 并行连接:多个TCP连接发起并行的HTTP请求
  • 持久连接:重用连接,消除TCP创建关闭时延 + 提高传输速率
  • 管道化连接:通过共享的TCP连接发起并行的HTTP请求

并行连接
弊端:
客户端的速率限制,导致连接发生竞争条件。
过多的并发请求消耗很多内存资源,导致客户端卡顿和服务器的压力陡增
所以Agent代理一般的并发数量会控制在4个左右
每个事务都会新建一个连接,会耗费时间和宽带
每次创建的连接速度一开始会被限制,每条的性能都有所降低

持久连接+并行连接 是最高效的方式:打开少量的并行连接,每条都是持久连接。

持久连接:在事务处理结束后将TCP连接保持在打开状态,以便为未来的HTTP请求重用现存的连接

  • HTTP/1.0 + “keep-alive”
  • HTTP/1.1 “persistent” 连接

并行事务

    原文作者:TCP
    原文地址: https://segmentfault.com/a/1190000011709222
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞