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

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

短连接

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第15讲——HTTP的连接管理

短连接 HTTP 协议最初(0.9/1.0)是个非常简单的协议,通信过程也采用了简单的“请求 - 应答”方式。 它底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,收到响应报文后会立即关闭连接。 因为客户端与…...

深度剖析Mybatis-plus Injector SQL注入器

背景 在项目中需要同时操作Sql Server 以及 MySQL 数据库,可能平时直接使用 BaseMapper中提供的方法习惯 了,不用的话总感觉影响开发效率,但是两个数据库的SQL语法稍微有点差别,有些暴露的方法并不能直接使用,所以便想…...

【Mysql实战】使用存储过程和计算同比环比

背景 同环比,是基本的数据分析方法。在各类调研表中屡见不鲜,如果人工向前追溯统计数据,可想而知工作量是非常大的。 标题复制10行,并且每行大于10个字符【源码解析】SpringBoot接口参数【Mysql实战】使用存储过程和计算同比环比…...

ChatGPT的前世今生,到如今AI领域的竞争格局,本文带你一路回看!

73年前,“机器思维”的概念第一次被计算机科学之父艾伦图灵(Alan Turing)提出,从此,通过图灵测试成为了人类在AI领域为之奋斗的里程碑目标。 73年后的今天,在AI历经了数十年的不断进化、迭代后&#xff0c…...

如何在JavaScript中获取当前时间yyyymmddhhmmss? (六种实现方式)

## 介绍 在编写JavaScript代码时,我们经常需要获取当前日期和时间。在本文中,我们将介绍几种获取当前时间并将其格式化为 yyyymmddhhmmss 的字符串的方法。 方法一:使用Date对象 在JavaScript中,我们可以使用 Date 对象来获取当…...

一、走进easyUI的世界

1.什么是easyUI? jQuery EasyUI是一组基于jQuery的UI插件集合体,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面。开发者不需要编写复杂的javascript,也不需要对css样式有深入的了解,开发者需要…...

2023 上半年软件设计师知识点复习总纲

前言:全国计算机技术与软件专业技术资格(水平)考试(以下简称IT职业资格考试)是由中华人民共和国人事部主管,国家计算机网络与信息安全管理中心主办的一项国家级、权威性的计算机职业技能水平认证考试。主要…...

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-3

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-3 垃圾收集器与内存分配策略垃圾收集算法标记-清除算法标记-复制算法标记-整理算法 垃圾收集器与内存分配策略 垃圾收集算法 标记-清除算法 最基础的垃圾收集算法是“标记-清除”(Mark-Sweep&#xff…...

vue3 cesium datav 可视化大屏

目录 0. 预览效果 1. 代码库包 2. 技术点 3. 一些注意事项(配置参数) 4. 相关代码详情 0. 预览效果 包含的功能: ① 地球按照一定速度自转 ② 修改加载的geojson面样式 ③ 添加 文字 标注! 1. 代码库包 直接采用vue-cli5 创建…...

python内置函数,推导式

abs:取绝对值 data abs(-10) pow:次方 data pow(2,5) sum:求和 num_list p[1,2,10,20] res sum(num_list) divmod取商和余数: v1,v2 divmod&…...

【Flink】DataStream API使用之Flink支持的数据类型

Flink的使用过程中,我们的数据都是定义好的 UserBehavior 类型,那还有没有其他更灵活的类型可以用呢?Flink 支持的数据类型到底有哪些? 1. Flink 的类型系统 Flink 作为一个分布式处理框架,处理的是以数据对象作为元…...

QT实现固高运动控制卡示波器

目录 一、固高示波器 二、基于QCustomPlot实现示波器 三、完整源码 一、固高示波器 固高运动控制卡自带的软件有一个示波器功能,可以实时显示速度的波形,可辅助分析电机的运行状态。但是我们基于sdk开发了自己的软件,无法再使用该功能&…...

洛谷P1157详解(两种解法,一看就会)

一、问题引出 组合的输出 题目描述 排列与组合是常用的数学方法,其中组合就是从 n n n 个元素中抽出 r r r 个元素(不分顺序且 r ≤ n r \le n r≤n),我们可以简单地将 n n n 个元素理解为自然数 1 , 2 , … , n 1,2,\dot…...

JavaScript异步编程和回调

目录 1、编程语言中的异步 2、JavaScript 3、回调 3.1在回调中处理错误 3.2回调的问题 3.2回调的替代方案 1、编程语言中的异步 默认情况下,JavaScript是同步的,并且是单线程…...

Qt开发笔记(Qt5.9.9下载安装环境搭建win10)

#1 Qt下载网站(国内、国外镜像) #2 Qt5.9.9安装选项 #3 配置系统环境变量 #4 创建测试项目 #1 Qt下载网站(国内、国外镜像) 官方下载地址(慢):http://download.qt.io/ 国内镜像网站 这里给大家…...

使用Plist编辑器——简单入门指南

本指南将介绍如何使用Plist编辑器。您将学习如何打开、编辑和保存plist文件,并了解plist文件的基本结构和用途。跟随这个简单的入门指南,您将掌握如何使用Plist编辑器轻松管理您的plist文件。 plist文件是一种常见的配置文件格式,用于存储应…...

Python常用的开发工具合集

​ Python是一种功能强大且易于学习的编程语言,被广泛应用于数据科学、机器学习、Web开发等领域。随着Python在各个领域的应用越来越广泛,越来越多的Python开发工具也涌现出来。但是,对于新手来说,选择一款合适的Python开发工具可…...

机器学习之线性回归

往期目录 python在线性规划中的应用 文章目录 一、线性回归算法概述1.1 什么是线性回归?1.2 线性回归算法原理1.3 线性回归的应用场景 二、线性回归算法Python实现2.1 导入必要的库2.2 随机生成数据集2.3 拟合模型2.4 预测结果2.5 结果可视化 三、完整代码 线性回归…...

中国系统正式发声!所有用户永久免费,网友:再见了,CentOS!

点关注公众号,回复“1024”获取2TB学习资源! 如果说:没有操作系统会怎么样? 对于个PC来说,无论是台式机、笔记本、平板等等,一切都变的一无是处,这些硬件对我们来说,和一堆废铁没什么…...

Oracle数据库坏块类故障

正常的数据块有其特有的固定格式,如果某数据块内部出现了混乱而导致Oracle无法读取,则可称其为坏块。数据库坏块的影响范围可大可小,严重时会导致数据库无法打开。当数据库出现坏块时,一般出现ORA-01578错误、ORA-10632错误或者OR…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

零基础设计模式——行为型模式 - 责任链模式

第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

如何在网页里填写 PDF 表格?

有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据&#xff…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...