详解TCP、HTTP中的保活机制 | Keepalive和Keep-Alive

目录

🌲 HTTP 的 Keep-Alive

🌲 TCP 的 Keepalive

🌲 最后总结

🌲 参考资料


TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗?

这是个好问题,应该有不少人都会搞混,因为这两个东西看上去太像了,很容易误以为是同一个东西。

事实上,这两个完全是两样不同东西,实现的层面也不同:

  • HTTP 的 Keep-Alive,是由应用层(用户态) 实现的,称为 HTTP 长连接;

  • TCP 的 Keepalive,是由 TCP 层(内核态) 实现的,称为 TCP 保活机制;

接下来,分别说说它们。

🌲 HTTP 的 Keep-Alive

HTTP 协议采用的是「请求-应答」的模式,也就是客户端发起了请求,服务端才会返回响应,一来一回这样子。

请求-应答

由于 HTTP 是基于 TCP 传输协议实现的,客户端与服务端要进行 HTTP 通信前,需要先建立 TCP 连接,然后客户端发送 HTTP  请求,服务端收到后就返回响应,至此「请求-应答」的模式就完成了,随后就会释放 TCP 连接。

一个 HTTP 请求

如果每次请求都要经历这样的过程:建立 TCP -> 请求资源 -> 响应资源 -> 释放连接,那么此方式就是 HTTP 短连接,如下图:

HTTP 短连接

这样实在太累人了,一次连接只能请求一次资源。

能不能在第一个 HTTP 请求完后,先不断开 TCP 连接,让后续的 HTTP 请求继续使用此连接?

当然可以,HTTP 的 Keep-Alive 就是实现了这个功能,可以使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销,这个方法称为 HTTP 长连接

HTTP 长连接

HTTP 长连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

怎么才能使用 HTTP 的 Keep-Alive 功能?

在 HTTP 1.0 中默认是关闭的,如果浏览器要开启 Keep-Alive,它必须在请求的包头中添加:

Connection: Keep-Alive

然后当服务器收到请求,作出回应的时候,它也添加一个头在响应中:

Connection: Keep-Alive

这样做,连接就不会中断,而是保持连接。当客户端发送另一个请求时,它会使用同一个连接。这一直继续到客户端或服务器端提出断开连接。

从 HTTP 1.1 开始, 就默认是开启了 Keep-Alive,如果要关闭 Keep-Alive,需要在 HTTP 请求的包头里添加:

Connection:close

现在大多数浏览器都默认是使用 HTTP/1.1,所以 Keep-Alive 都是默认打开的。一旦客户端和服务端达成协议,那么长连接就建立好了。

HTTP 长连接不仅仅减少了 TCP 连接资源的开销,而且这给 HTTP 流水线技术提供了可实现的基础。

所谓的 HTTP 流水线,是客户端可以先一次性发送多个请求,而在发送过程中不需先等待服务器的回应,可以减少整体的响应时间。

注意!Keep-Alive为HTTP 流水线技术提供了可实现的基础,这个基础说的只是开启Keep-Alive,可以实现HTTP长连接(持久连接)。而实现HTTP流水线技术的是HTTP1.1引入的管道机制(Pipelining),管道机制允许客户端同时发出多个请求,然后服务端按照顺序响应。不要搞混了!参考资料:Keep-Alive和Pipelining

举例来说,客户端需要请求两个资源。以前的做法是,在同一个 TCP 连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。HTTP 流水线机制则允许客户端同时发出 A 请求和 B 请求。

右边为 HTTP 流水线机制

但是服务器还是按照顺序响应,先回应 A 请求,完成后再回应 B 请求。

而且要等服务器响应完客户端第一批发送的请求后,客户端才能发出下一批的请求,也就说如果服务器响应的过程发生了阻塞,那么客户端就无法发出下一批的请求,此时就造成了「队头阻塞」的问题。

可能有的同学会问,如果使用了 HTTP 长连接,如果客户端完成一个 HTTP 请求后,就不再发起新的请求,此时这个 TCP 连接一直占用着不是挺浪费资源的吗?

对没错,所以为了避免资源浪费的情况,web 服务软件一般都会提供 keepalive_timeout 参数,用来指定 HTTP 长连接的超时时间。

比如设置了 HTTP 长连接的超时时间是 60 秒,web 服务软件就会启动一个定时器,如果客户端在完后一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,就会触发回调函数来释放该连接。

HTTP 长连接超时

🌲 TCP 的 Keepalive

TCP 的 Keepalive 这东西其实就是 TCP 的保活机制,它的工作原理,我之前的文章也讲解过,在这里我们重新温习一下:

定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个「探测报文」,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。

在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75  
net.ipv4.tcp_keepalive_probes=9
  • tcp_keepalive_time=7200:表示保活时间是 7200 秒(2小时),也就 2 小时内如果没有任何连接相关的活动,则会启动保活机制

  • tcp_keepalive_intvl=75:表示每次检测间隔 75 秒;

  • tcp_keepalive_probes=9:表示检测 9 次无响应,认为对方是不可达的,从而中断本次的连接。

也就是说在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接。

如果两端的 TCP 连接一直没有数据交互,达到了触发 TCP 保活机制的条件,那么内核里的 TCP 协议栈就会发送探测报文。

  • 如果对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来。

  • 如果对端主机崩溃,或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡

注:在探测过程中,对端主机会处于以下四种状态之一:

所以,TCP 保活机制可以在双方没有数据交互的情况,通过探测报文,来确定对方的 TCP 连接是否存活,这个工作是在内核完成的。

TCP 保活机制

注意,应用程序若想使用 TCP 保活机制需要通过 socket 接口设置 SO_KEEPALIVE 选项才能够生效,如果没有设置,那么就无法使用 TCP 保活机制。

🌲 最后总结

HTTP 的 Keep-Alive 也叫 HTTP 长连接,该功能是由「应用程序」实现的,可以使得用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,减少了 HTTP 短连接带来的多次 TCP 连接建立和释放(销毁)的开销。

TCP 的 Keepalive 也叫 TCP 保活机制,该功能是由「内核」实现的,当客户端和服务端长达一定时间没有进行数据交互时,内核为了确保该连接是否还有效,就会发送探测报文,来检测对方是否还在线,然后来决定是否要关闭该连接。

🌲 参考资料

| 实战——我用“大白鲨”让你看见 TCP | TCP、HTTP中的保活机制keep-alive |

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DNS协议--笔记

引自: 什么是DNS? - 知乎 (zhihu.com) 超详细 DNS 协议解析 - 知乎 (zhihu.com) IP 地址:一长串能够唯一地标记网络上的计算机的数字域名:又称网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组…

rust语言精要

rust基本组成 编译器:Rust是一门静态编译型语言。Rust官方的编译器叫rustc,负责将 Rust源代码编译为可执行文件或其他库文件(.a、.so、.lib、.dll等)。特点是跨平台的,后端用了LLVM。 核心库和标准库 Rust语言的语法由…

Prometheus之PromQL语法详解及使用方法

本文是向大家介绍Prometheus中PromQL的查询语法以及常用语句,可以帮助大家理解和掌握Prometheus的查询语言。1、简介Prometheus是通过指标名称(metrics name)以及对应的一组标签(labelset)唯一定义一条时间序列。指标名…

如何选择Facebook的各种广告形式来获取用户?

Facebook广告是吸引潜在客户的重要工具,但盲目投放广告却很难达到理想效果。在选择广告格式时,需要考虑到品牌和业务目标,以及目标受众的特征和偏好。下面介绍8种Facebook广告格式,不论您是想用视频、图片或文字,还是结…

云端Docker搭建ABY库以及本地CLion使用

文章目录ABY的搭建以及使用前言ABY库的下载、安装及测试CLion配置后续杂项项目改名使用其他的库最后ABY的搭建以及使用 前言 仅做记录,仅供参考,不同人有不同的使用方式命令手敲,可能有错,自己辨识勿问,我懂的也不多…

什么牌子的蓝牙耳机音质好又便宜?国产音质好的蓝牙耳机推荐

目前的蓝牙耳机市场涌现了越来越多的蓝牙耳机,不同价位主打不同的性能,有主打佩戴的,主打音质的,主打降噪的,主打游戏的等等。那么,什么牌子的蓝牙耳机音质好又便宜?针对这个问题,我…

Redis详解(redis线程模式、数据持久化机制、主从复制、缓存穿透、缓存击穿等)

一.redis概述redis主要用作数据库、缓存和消息中间件, 支持多种语言, 是基于内存的key-value数据结构存储系统. redis支持数据的持久化, 可以将内存中的数据保存在磁盘中, 重启的时候可以再次加载进行使用.redis不仅仅支持key-value数据结构, 还支持list, set, hash等数据结构.…

CHAPTER 7 HPC集群部署 - hadoop

HPC集群部署 - hadoop1. 介绍2. 优点3. 架构及相关组件3.1 HDFS3.1.1 NameNode3.1.2 DataNode3.1.3 Secondary NameNode3.1.4 Client(客户端)3.2 Mapreduce(分布式计算框架)3.3. HBase(分布式列存储数据库)3.4 Zookeeper&#xff…

【其它】玩一玩无线网桥PicoStation M2

一、无线网桥是什么? 无线网桥就是代替网线实现网络连接的装置。看下面这个场景,摄像头与录像机之间可以直接用网线连接,但遇到两者相距较远的情况,铺设网线成本太高,这时候可以用无线网桥进行连接。无线网桥一般成对…

SSM项目之租赁汽车管理

项⽬描述 汽⻋租赁管理系统,管理系统中不仅有客户的管理还有⻋辆租赁的管理,租赁⻋辆公司对于租⻋的流程,租⻋过程的问题,对于客户的维护及不同维度统计租⻋的情况做数据化管理,⽅便租⻋公司更好的维护⻋辆和⻋辆的信…

易基因: m6A RNA甲基化研究的前期探索性实验思路|干货系列

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 近年来,m6A RNA甲基化作为国家自然科学基金表观遗传学研究的热门领域,相关研究成果层出不穷,高分文章不断。研究方向包括疾病发生发展、发育和分化、环…

误删磁盘恢复方法

一、工具如下:1、磁盘分区恢复工具(分区助手 9.8.0)---链接:https://pan.baidu.com/s/1t3siEwtYZl7XtcNJ8t5oLg 提取码:9tsy2、DiskGenius 磁盘信息查看工具(修复要收费):链接:https://pan.baid…

(源码篇02)webpack5中的事件调度系统和NormalModuleFactary核心逻辑

1. 书接上回,从 this.factorizeQueue.add(options, callback); 开始 不是很清楚上下文的兄弟,可以去看下我之前写的 (源码篇01)浅析webpack5中Compiler中重要的hook调用过程。 此文比较干,各位读者开始阅读前&#xf…

反射器和Spring中的IOC/DI

1.什么是反射 1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 2)Java属于先编译…

LC-1637. 两点之间不包含任何点的最宽垂直区域(模拟)

1637. 两点之间不包含任何点的最宽垂直区域 难度中等25 给你 n 个二维平面上的点 points ,其中 points[i] [xi, yi] ,请你返回两点之间内部不包含任何点的 最宽垂直区域 的宽度。 垂直区域 的定义是固定宽度,而 y 轴上无限延伸的一块区域…

户外徒步用什么耳机好?户外运动耳机推荐

作为一个徒步爱好者,在长时间的户外行走的途中自然会准备一个耳机来陪伴我。市面上各种运动型耳机层出不穷,价格也从几十到上千不等。但是喜爱的运动项目不同对运动耳机的需求也不一样。今天我们就来盘带点一下市面上各产品的性能参数,哪一款…

如何理解文件描述符和文件指针,两者的区别和联系?

下面是一些预备的知识: 我们先来回顾一下这张图 如果你对此图并不了解,甚至完全都知道这张图,那么下面的内容了解起来可能并不容易。 第一,首先我们要明确的认识一点,文件流指针是各种语言对系统调用接口的封装&…

代码随想录算法训练营第四十二天 | 416. 分割等和子集

背包问题之01背包问题基础: 视频讲解 (一)常见要求: 有n件物品,每个物品只有一个,和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次&a…

【操作系统】模块六 :文件系统 (Linux文件目录 | 文件系统 | B树 B+树 |分布式文件系统)

文章目录【操作系统】模块六 :文件系统Linux的文件目录分区结构挂载目录结构/usr(Unix System Resource) 包含系统需要的资源文件,通常应用程序会把后来安装的可执行文件 也放到这个目录下,比如说文件系统底层设计 FAT…

树莓派学习笔记(十二)Linux驱动认知及编译加载驱动

文章目录一、Linux驱动认知二、内核空间1、如何找到相关的驱动2、主设备号和次设备号3、驱动链表:管理所有设备的驱动4、驱动插入链表的顺序由设备号检索5、驱动代码的开发三、驱动编写、编译、测试四、驱动阶段性总结一、Linux驱动认知 Linux驱动分为用户空间、内…
最新文章