当前位置: 首页 > news >正文

《HTTP权威指南》 第4章 连接管理

带着问题学习(通常是面试考点)

  • HTTP是如何使用TCP连接的
  • TCP连接的时延、瓶颈及存在的障碍
  • HTTP的优化,包括并行连接、keep-alive(持久连接)和管道化连接
  • 管理连接时应该和不应该做的事

TCP连接

在这里插入图片描述
在这里插入图片描述
TCP的数据通过IP分组(或IP数据报)的小数据块来发送。

协议顺序HTTP (>> SSL or TLS) >> TCP >> IP
在这里插入图片描述

数据传输过程:

  1. HTTP以的形式将数据报文通过TCP连接进行按序传输
  2. TCP收到数据流后,将数据流砍成小数据块(称作),将封装IP分组中,通过因特网传输

IP分组包括:一个IP分组首部(通常20字节) + 一个TCP段首部(通常20字节) + 一个TCP数据块(0或多个字节)

  • IP分组首部:源和目的IP地址、长度、其他标记
  • TCP段首部:TCP端口号、TCP控制标记、其他数据排序和完整性检查的数值

TCP连接识别<源IP地址、源端口号、目的IP地址、目的端口号>
TCP通过端口号保持多个连接持续运行,这4个值唯一的定义了一条连接,两条不同TCP连接不能拥有4个完全相同的地址组件值。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

套接字API允许用户创建TCP的端点数据结构,将这些端点与远程服务器的TCP端点进行连接,并对数据流进行读写。

对TCP接口进行编程所需的常见套接字接口函数伪代码
在这里插入图片描述

TCP客户端与服务器是如何通过TCP套接字接口进行通信的:
在这里插入图片描述

HTTP事务的时延

回顾一下:HTTP事务 = 请求命令(HTTP方法)+ 响应结果

串行HTTP事务的时间线 = DNS查询 + TCP连接&接受应答 + 发送请求 + 处理 + 响应 + 关闭连接
在这里插入图片描述
HTTP事务的时延原因:

  • DNS解析URI中的主机名为IP地址
  • TCP请求连接需要等待接受应答
  • 发送报文及处理请求报文
  • 服务器回送HTTP响应

TCP网络时延的大小取决于硬件速度网络服务器负载报文尺寸客户端与服务器之间的距离TCP协议的技术复杂性也会对时延产生影响。

常见的TCP时延:

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

TCP连接的握手时延

在发送数据前,TCP要传送两个分组来建立连接。
在这里插入图片描述
TCP三次握手:a SYN请求建立连接 >> b SYN+ACK接受连接 >> c ACK确认成功建立连接

延迟确认

如果是小的HTTP事务,那么TCP连接就占了大量时间,由于确认报文很小,所以TCP允许在发往相同方向的输出数据分组中对其进行“捎带”(有点像夹带私货…),将返回的确认信息与输出的数据分组结合,剩下一次请求报文的时间,此行为称为“延迟确认算法”。

延迟确认算法会在特定窗口时间(200~300ms)内将输出确认存放在缓存区中,等待能够捎带的输出数据分组,没有就单独发送确认。

TCP慢启动

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

TCP慢启动限制了一个TCP端点在任意时间可以传输的分组数。每成功接收一个分组,发送端就有了发送2个分组的权限。有大量数据要发送也无法一次发送出去。必须发一个等待确认,然后发2个,都确认再发4个,以此类推。这种方式称为“打开拥塞窗口“,所以新连接比已交换过数据的连接慢一些

Nagle算法和TCP NODELAY

Nagle算法鼓励发送全尺寸的段,将已确认的分组数据缓存起来,等待传输中的分组被确认,当缓存积累了足够发送一个全尺寸的段再将缓存数据发出去。

但小的报文可能无法填满一个分组会因为等待永不会到来的额外数据而产生时延。且确认分组自身因“延迟确认算法”而延迟100~200毫秒。

所以HTTP应用程序通常会设置参数TCP NODELAY禁用Nagle算法。

TIME_WAIT累计和端口耗尽

当TCP端点关闭连接时,会在内存中维护一个小的控制快,用来记录最近关闭的IP地址和端口号,保证在一段时间内不会创建相同地址和端口的新连接。这段时间通常是最大分段使用期的两倍(2MSL,通常2分钟)。

TCP连接的4个值中:源IP、源端口、目标IP、目标端口,只有源端口可以随意改变的。

由于源端口的数量有限(比如6万),2MSL(比如120秒)内连接不能重用,那么连接率上限就为6万➗120秒=500次/秒。不超过500就不会遇到端口耗尽的问题。
要修正这个问题,可以增加客户端会负载生成机器的数量,或者确保循环使用几个虚拟IP来增加更多的连接组合。

HTTP连接的处理

串型事务处理时延

连接时延和慢启动时延叠加
在这里插入图片描述

HTTP优化1:并行连接

HTTP允许客户端打开多条连接,并行地执行多个HTTP事务。
在这里插入图片描述
⚠️注意:如果客户端网络带宽不足,那么大部分时间可能都在传送数据,多个事务的连接很快会耗尽所有可用的带宽。同时请求也会造成服务器性能严重下降,为了均衡,浏览器会限制并行连接的总数为一个较小的值(通常是4个)。

HTTP优化2:持久连接

初始化了对某服务器HTTP请求的应用程序很可能在不久后对该服务器发起更多的请求,这种性质被称为“站点局部性”。

因此HTTP/1.1允许HTTP设备在事务处理结束后将TCP连接保持打开状态,以便后续请求重用连接。在事务处理结束后保持打开状态的TCP连接被称为“持久连接”。

持久连接降低了时延和连接建立的开销(已调谐),但是容易产生大量空闲连接,需要特别注意。

持久连接类型1:HTTP/1.0的keep-alive连接

通过Connection: Keep-Alive保持连接

支持max设置希望保持连接的上限数,timeout设置希望保持连接的时间,如:Keep-Alive: max=5, timeout=120,但对方不一定会同意。
在这里插入图片描述
如果服务器支持keep-alive参数,需要回送一个Connection: Keep-Alive,否则不回送。

很多老的代理都是“盲中继”,只转发不对Connection首部作处理。当通过作为盲中继使用的哑代理连接时,会出现图示情形:
在这里插入图片描述
服务器返回响应后,哑代理返回数据后由于等待连接关闭,会忽略连接上的新请求,导致了下一条请求被挂起。这种错误的通信会使浏览器一直处于挂起状态,直到连接超时关闭。

为避免出现上述通信问题,现代的代理都绝不能转发Connection首部和出现在该首部值中的首部。

一个变通做法是,发送非标准的Proxy-Connection扩展首部,哑代理转发后服务器会忽略此首部,聪明的代理会转换为Connection首部发送,以收到预期效果。但是如果代理中有哑代理又有聪明的代理就会再次出现问题…😂

持久连接类型2:HTTP/1.1的persistent连接

HTTP/1.1默认所有连接都是持久连接,如果关闭连接就显式添加一个Connection: Close

HTTP优化3:管道化连接

HTTP/1.1允许在持久连接上可选地使用请求管道,在响应到达之前,将多条请求放入队列

管道化连接的限制:

  • 若HTTP客户端无法确认连接是持久的,就不应该使用管道
  • 必须按照与请求相同的顺序回送HTTP响应
  • HTTP客户端必须做好连接会在任意时刻关闭的准备,还要准备好重发未完成的请求
  • HTTP客户端不应该用管道化的方式发送可能会产生副作用的请求(比如POST),因为出错时无法安全的重试POST这样的非幂等请求

    幂等(Idempotent): 一个操作如果执行一次多次对系统状态产生的改变完全相同(或者说效果等同于只执行一次),那么这个操作就是幂等的。
    非幂等(Non-idempotent): 一个操作如果执行多次与执行一次对系统状态产生的改变不同(通常会产生额外的副作用),那么这个操作就是非幂等的。

在这里插入图片描述
要发送一条非幂等的请求,需要等待来自前一条请求的响应状态。
一定不能自动重试非幂等的方法。比如,大多数浏览器会在重载一个缓存的POST响应时提供一个对话框,询问用户是否再次发起事务处理。

正常关闭连接

完全关闭:TCP输入和输出都关闭
半关闭:单独关闭TCP输入或输出

在这里插入图片描述
关闭连接的输出信道总是安全的,关闭连接的输入信道比较危险
如果另一端向你已关闭的输入信道发送数据,操作系统就会向另一端回送一条TCP“连接被对端重置”的报文,将删除对端还未读取的所有缓存数据
在这里插入图片描述
正常关闭的应用程序应该首先关闭输出信道两端都告诉对方不再发送任何数据之后,再完全关闭连接,就不会有重置的危险。

http://www.lqws.cn/news/466489.html

相关文章:

  • RA4M2开发涂鸦模块CBU(3)----定时器GPT-PWM调光
  • 18年磨一剑!开利科技启动数字化增量投资新时代
  • 探索 Vue 替代方案
  • Linux文件元信息完全指南:权限、链接与时间属性
  • jar is missing
  • ubuntu22.04下ch341驱动问题
  • Web攻防-XSS跨站Cookie盗取数据包提交网络钓鱼BEEF项目XSS平台危害利用
  • 广州华锐互动:以技术创新引领虚拟现实体验新高度
  • 私有规则库:企业合规与安全的终极防线
  • Go 语言 GMP 调度模型解析
  • 从流量为王到留量为王:开源链动2+1模式、AI智能名片与S2B2C商城小程序的协同创新路径
  • 推客小程序系统开发全攻略:构建社交电商新生态
  • 亚马逊认证考试系列 - 第一部份:基础服务 - AWS SAA C03
  • Maven-添加子模块
  • SylixOS 下的消息队列
  • SQLite 数据库操作完整指南
  • 逆向入门(14、15)程序逆向篇-Brad Soblesky.1-fty_crkme3
  • AWS-SAA 第二部份:安全性和权限管理
  • 操作系统进程与线程核心知识全览
  • Softhub软件下载站实战开发(六):软件配置面板实现
  • LeetCode 1432.改变一个整数能得到的最大差值:暴力模拟/贪心
  • 企业公用电脑登录安全管控的终极方案:ASP操作系统安全登录管控方案
  • c++ 虚继承
  • 【软考高级系统架构论文】论云上自动化运维及其应用
  • 嵌入式开发之嵌入式系统架构如何搭建?
  • Spring与SLF4J/Logback日志框架深度解析:从源码看日志系统设计
  • elasticsearch安装ik分词器
  • 3.1 Android NDK交叉编译FFmpeg
  • 领域驱动设计(DDD)【3】之事件风暴
  • React 重识