HTTP第15讲——HTTP的连接管理

news2024/11/28 8:45:07

短连接

HTTP 协议最初(0.9/1.0)是个非常简单的协议,通信过程也采用了简单的“请求 - 应答”方式。
它底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,收到响应报文后会立即关闭连接。
因为客户端与服务器的整个连接过程很短暂,不会与服务器保持长时间的连接状态,所以就被称为“短连接”(short-lived connections)。早期的 HTTP 协议也被称为是“无连接”的协议。
在这里插入图片描述
在这里插入图片描述

举例子:

假设你的公司买了一台打卡机,放在前台,因为这台机器比较贵,所以专门做了一个保护罩盖着它,公司要求每次上下班打卡时都要先打开盖子,打卡后再盖上盖子。
可是偏偏这个盖子非常牢固,打开关闭要费很大力气,打卡可能只要 1 秒钟,而开关盖子却需要四五秒钟,大部分时间都浪费在了毫无意义的开关盖子操作上了。
可想而知,平常还好说,一到上下班的点在打卡机前就会排起长队,每个人都要重复“开盖 -打卡 - 关盖”的三个步骤,你说着急不着急。
在这个比喻里,打卡机就相当于服务器,盖子的开关就是 TCP 的连接与关闭,而每个打卡的人就是 HTTP 请求,很显然,短连接的缺点严重制约了服务器的服务能力,导致它无法处理更多的请求。

长连接

针对短连接暴露出的缺点,HTTP 协议就提出了“长连接”的通信方式,也叫“持久连接”(persistent connections)、“连接保活”(keep alive)、“连接复用”(connection reuse)。
其实解决办法也很简单,用的就是“成本均摊”的思路,既然 TCP 的连接和关闭非常耗时间,那么就把这个时间成本由原来的一个“请求 - 应答”均摊到多个“请求 - 应答”上。
这样虽然不能改善 TCP 的连接效率,但基于“分母效应”,每个“请求 - 应答”的无效时间就会降低不少,整体传输效率也就提高了。

短连接与长连接的对比示意图

在这里插入图片描述
继续用刚才的打卡机的比喻,公司也觉得这种反复“开盖 - 打卡 - 关盖”的操作太“反人类”了,于是颁布了新规定,早上打开盖子后就不用关上了,可以自由打卡,到下班后再关上盖子。
这样打卡的效率(即服务能力)就大幅度提升了,原来一次打卡需要五六秒钟,现在只要一秒就可以了,上下班时排长队的景象一去不返,大家都开心。

连接相关的头字段

由于长连接对性能的改善效果非常显著,所以在 HTTP/1.1 中的连接都会默认启用长连接。不需要用什么特殊的头字段指定,只要向服务器发送了第一次请求,后续的请求都会重复利用第一次打开的 TCP 连接,也就是长连接,在这个连接上收发数据。
当然,我们也可以在请求头里明确地要求使用长连接机制,使用的字段是 Connection,值是“keep-alive”。
不过不管客户端是否显式要求长连接,如果服务器支持长连接,它总会在响应报文里放一个“Connection: keep-alive”字段,告诉客户端:“我是支持长连接的,接下来就用这个TCP 一直收发数据吧”。
不过长连接也有一些小缺点,问题就出在它的“长”字上。
因为 TCP 连接长时间不关闭,服务器必须在内存里保存它的状态,这就占用了服务器的资源。如果有大量的空闲长连接只连不发,就会很快耗尽服务器的资源,导致服务器无法为真正有需要的用户提供服务。
所以,长连接也需要在恰当的时间关闭,不能永远保持与服务器的连接,这在客户端或者服务器都可以做到。
在客户端,可以在请求头里加上“Connection: close”字段,告诉服务器:“这次通信后就关闭连接”。服务器看到这个字段,就知道客户端要主动关闭连接,于是在响应报文里也加上这个字段,发送之后就调用 Socket API 关闭 TCP 连接。
服务器端通常不会主动关闭连接,但也可以使用一些策略。拿 Nginx 来举例,它有两种方式:
1.使用“keepalive_timeout”指令,设置长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开连接,避免空闲连接占用系统资源。
2.使用“keepalive_requests”指令,设置长连接上可发送的最大请求次数。比如设置成1000,那么当 Nginx 在这个连接上处理了 1000 个请求后,也会主动断开连接。

另外,客户端和服务器都可以在报文里附加通用头字段“Keep-Alive: timeout=value”,限定长连接的超时时间。但这个字段的约束力并不强,通信的双方可能并不会遵守,所以不太常见。

队头阻塞

看完了短连接和长连接,接下来就要说到著名的“队头阻塞”(Head-of-line blocking,也叫“队首阻塞”)了。
“队头阻塞”与短连接和长连接无关,而是由 HTTP 基本的“请求 - 应答”模型所导致的。
因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。
如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本。
在这里插入图片描述
还是用打卡机做个比喻。上班的时间点上,大家都在排队打卡,可这个时候偏偏最前面的那个人遇到了打卡机故障,怎么也不能打卡成功,急得满头大汗。等找人把打卡机修好,后面排队的所有人全迟到了。

性能优化

因为“请求 - 应答”模型不能变,所以“队头阻塞”问题在 HTTP/1.1 里无法解决,只能缓解,有什么办法呢?
公司里可以再多买几台打卡机放在前台,这样大家可以不用挤在一个队伍里,分散打卡,一个队伍偶尔阻塞也不要紧,可以改换到其他不阻塞的队伍。
这在 HTTP 里就是“并发连接”(concurrent connections),也就是同时对一个域名发起多个长连接,用数量来解决质量的问题。
但这种方式也存在缺陷。如果每个客户端都想自己快,建立很多个连接,用户数×并发数就会是个天文数字。服务器的资源根本就扛不住,或者被服务器认为是恶意攻击,反而会造成“拒绝服务”。
所以,HTTP 协议建议客户端使用并发,但不能“滥用”并发。RFC2616 里明确限制每个客户端最多并发 2 个连接。不过实践证明这个数字实在是太小了,众多浏览器都“无视”标准,把这个上限提高到了 6~8。后来修订的 RFC7230 也就“顺水推舟”,取消了这个“2”的限制。
公司发展的太快了,员工越来越多,上下班打卡成了迫在眉睫的大问题。前台空间有限,放不下更多的打卡机了,怎么办?那就多开几个打卡的地方,每个楼层、办公区的入口也放上三四台打卡机,把人进一步分流,不要都往前台挤。
这个就是“域名分片”(domain sharding)技术,还是用数量来解决质量的思路。
HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如shard1.chrono.com、shard2.chrono.com,而这些域名都指向同一台服务器www.chrono.com,这样实际长连接的数量就又上去了,真是“美滋滋”。不过实在是有点“上有政策,下有对策”的味道。

小结

  1. 早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;
  2. HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;
  3. 服务器会发送“Connection: keep-alive”字段表示启用了长连接;
  4. 报文头里如果有“Connection: close”就意味着长连接即将关闭;
  5. 过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;
  6. “队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”技术缓解。

PS:本文是观看极客之后的笔记。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/537742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-numpy_数据归一化

Numpy 数据归一化:介绍和原理 随着大数据和机器学习的发展,数据预处理变得越来越重要。对于数据进行标准化和归一化是其中的一项常见操作。本文将介绍numpy中的数据归一化,包括其原理和实现方法。 什么是数据归一化? 在数据处理…

Spring AOP的概念和使用

什么是AOP AOP是一种思想,它叫做面向切面编程,简单的来说就是对某一类事请做集中处理。比如说:登录效验功能,在使用AOP之前,我们进行登录效验需要在每个方法中写一遍登录效验的代码;使用AOP后,…

chatgpt赋能Python-numpy提取数据

Numpy提取数据:一种高效处理数据的方法 Numpy是Python中一个用于科学计算的库,它提供了一些高效的数值计算工具和数据结构。其中一个重要的功能是对大量数据进行高效的处理与分析。本文将介绍Numpy提取数据的用法,帮助您更高效地处理数据。 …

Java参数绑定(包括按值传递和按引用传递)

在Java中,参数绑定是一种将实际参数值传递给方法或函数的过程。在方法调用中,参数绑定决定了方法的形式参数(在方法声明中定义的参数)和实际参数(传递给方法的参数)之间的关系。 Java中的参数绑定有两种形…

chatgpt赋能Python-numpy数据归一化

Numpy数据归一化:什么是归一化以及为什么要归一化? 当我们处理数据时,我们常常要将它们归一化。归一化是将数值范围缩放到标准范围内的过程。这可以确保不同的特征或变量在计算机算法中具有相同的权重。这对于一些机器学习算法、人工神经网络…

chatgpt赋能Python-mac_python怎么用

如何在Mac上使用Python进行编程? 如果你是一位Python开发者,想在Mac上进行编程,本篇文章将会告诉你如何使用Python在Mac上进行编程。首先,你需要确认你的Mac上是否安装了Python,如果你是新手,可以去Python…

nginx(七十六)nginx与HTTP请求行的深入探讨

一 nginx与请求行相关 nginx处理来自客户端的HTTP请求行和请求头 ① 关于请求行的变量 $request $request_method SP $request_uri SP $server_protocol "案例讲解" ② nginx作为服务端接收关于method控制 1) 请求方法和支持的协议版本包含如下: -->协议…

离线安装apisix

公司部分机器因为某些原因无法联网,只能离线安装apisix,折腾了很久,走了很多弯路,记录一下安装过程。 下载所有的包 安装epel源 sudo yum install epel-release在home下创建文件夹/apisix-dependence 下载apache-apisix-repo以…

chatgpt赋能Python-mac上的python

在Mac上使用Python编程的好处 作为一名有10年Python编程经验的工程师,我必须说Mac是一个出色的编程工作台。Mac操作系统本质上就是一个整合了各种开发工具的平台,为Python编程提供了很好的支持。这篇文章将介绍在Mac上使用Python编程的好处。 简单易用…

VOSviewer安装、环境配置及中英文文献的分析

VOSviewer介绍: VOSviewer是一个用于构建和可视化文献计量网络的软件工具。例如,这些网络可能包括期刊、研究人员或单个出版物,它们可以基于引文、书目耦合、共同引用或共同作者关系构建。VOSviewer 还提供文本挖掘功能,可用于构…

总线(计组)

概概述 基本概念 1、总线:是构成计算机互联的机构,是多个系统功能部之间进行数据传输的公共通路 2、总线的分类: 内部总线、系统总线、IO总线 内部总线:cpu连接寄存器及各运算部件的总线 系统总线:cpu连接其他高速功…

Typora的自定义主题

Typora的自定义主题 修改我们的Typora主题1. 在文件夹C:\Users\Peter\AppData\Roaming\Typora\themes中,加入下面的css文件即可,命名为my.css。my.css内容 2. 选择你的主题为my3. 效果如图 注意:如果你的字体没有完全像我一样,是因…

学习RHCSA的day.03

目录 2.6 Linux系统的目录结构 2.7 目录操作命令 2.8 文件操作命令 2.6 Linux系统的目录结构 1、Linux目录结构的特点 分区加载于目录结构: 使用树形目录结构来组织和管理文件。整个系统只有一个位于根分区的一个根目录(树根)、一棵树。…

chatgpt赋能Python-mac版python教程

了解Mac版Python教程 Python编程语言越来越受欢迎,是由其简单易学、使用广泛的特点所得。Mac用户也喜欢使用Python进行编程,因为Python在macOS中得到良好的支持。在本篇文章中,我们将介绍一些最受欢迎的Mac版Python教程,并提供一…

chatgpt赋能Python-a____python

理解Python的a[:]语法 Python是一门高级编程语言,它被广泛应用于数据分析、机器学习、人工智能等领域。在Python编程中,有一个很重要的语法就是a[:]。 在本文中,我们将介绍这个语法的含义、作用和用法,并帮助读者更好地理解这个语…

动态规划算法:解决复杂问题的利器

文章目录 摘要引言动态规划的基本原理动态规划的应用场景动态规划的实际代码示例总结与展望 动态规划算法的优缺点优点:缺点: 总结: 摘要 动态规划(Dynamic Programming)是一种高效解决复杂问题的算法方法&#xff0c…

如何学习网络安全?

近半年我一直在整理网络安全相关资料,对于网络安全该怎么入门我谈谈我的看法,网络安全一直处于法律的边缘,学的不好或者剑走偏锋一下子人就进去了,所以我建议入门前先熟读《网络安全法》,除此之外还有《互联网安全产品…

AVL树(平衡二叉搜索树)

如果BST树插入的顺序是有序的,那么BST树就会退化成一个双链表结构,查询的速率就会很慢, 所以有了AVL树的意义。 AVL树的定义: 是具有下列性质的二叉搜索树 1、它的左子树和右子树都是AVL树 2、左子树和右子树的高度之差的绝对值…

Java --- redis7之redisson的使用

目录 一、自研分布式锁核心 二、redlock红锁算法 Distributed locks with redis 2.1、设计理念 2.2、容错公式 2.3、单机案例实现 三、redisson源码分析 四、多机案例 4.1、启动三台docker的redis7 4.2、进入redis 一、自研分布式锁核心 1、按照JUC里面java.util.conc…

linux kernel pwn

基础知识 内核概述 内核架构 通常来说我们可以把内核架构分为两种:宏内核和微内核,现在还有一种内核是混合了宏内核与微内核的特性,称为混合内核。 宏内核(Monolithic kernel),也译为集成式内核、单体…