提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、什么是keepAlive?
  • 二、TCP之KeepAlive详解
    • 2.1 为什么需要KeepAlive?
    • 2.2 如何开启KeepAlive?
    • 2.3 keepAlive的局限性
  • HTTP之Keep-Alive详解
    • 3.1 http为什么需要Keep-Alive?

前言

近日,我的朋友广叔来和我讨论keepalive的相关知识,由于他最近项目上要用,但是他呀又不太了解,所以我就给他讲解了一番,keepalive其实用的也挺多的,在此记录下,希望朋友们用到的话,也能大致明白,这到底是个啥~


一、什么是keepAlive?

广叔:你能给我说说keepAlive是什么吗?最近项目上要用,但是我又不懂,领导还居然让我负责。。。

令狐冲:你们领导挺大胆的呀,居然让你负责,那公司离破产不远了~

广叔:少哔哔,你就直接说吧~我真的要用。。

令狐冲:其实你这问的就很不专业~,你首先要明确你想了解的是哪一种,是TCP的 KeepAlive 还是HTTP的 Keep-Alive。这俩可是完全不同的概念,绝对不能混淆的。

广叔:哦哦,看出来了,写法都不同,HTTP的KeepAlive写法是Keep-Alive,TCP的是KeepAlive。

令狐冲:TCP是传输层的一种协议,而HTTP是应用层的一种协议。不要混淆!

广叔:那你要不先讲讲TCP的keepalive?

令狐冲:TCP的keepalive是侧重在保持客户端和服务端的连接,一方会不定期发送心跳包给另一方,当一方端掉的时候,没有断掉的定时发送几次心跳包,如果间隔发送几次,对方都返回的是RST,而不是ACK,那么就释放当前链接。

广叔:那这个有啥用吗?没想出来呀。。

令狐冲:那你设想一下,如果tcp层没有keepalive的机制,一旦一方断开连接却没有发送FIN给另外一方的话,那么另外一方会一直以为这个连接还是存活的,几天,几月。那么这对服务器资源的影响是很大的。

广叔:哎呦,还真是的,之前没想到啊,没有keepalive的话,TCP的中可能存在大量的无效连接却占着很多资源。

广叔:那HTTP中的keep-alive呢?http连接不就是客户端连接上服务端,然后结束请求后,由客户端或者服务端进行http连接的关闭。下次再发送请求的时候,客户端再发起一个连接,传送数据,关闭连接。这么个流程反复吗?不会有问题的呀?

令狐冲:正常的情况确实是你说的那样子的,但是一旦客户端发送connection:keep-alive头给服务端,且服务端也接受这个keep-alive的话,两边对上暗号,这个连接就可以复用了,一个http处理完之后,另外一个http数据直接从这个连接走了。减少新建和断开TCP连接的消耗。

广叔:wow!,这个操作也太骚了吧?太省资源了。

广叔:我简单概括下:HTTP协议的Keep-Alive意图在于短时间内连接复用,希望可以短时间内在同一个连接上进行多次请求/响应。

广叔:TCP的KeepAlive机制意图在于保活、心跳,检测连接错误。当一个TCP连接两端长时间没有数据传输时(通常默认配置是2小时),发送keepalive探针,探测链接是否存活。

令狐冲:是的,你要记住HTTP的Keep-Alive和TCP的KeepAlive不是一回事,tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。而http的keep-alive说的是如何避免进行重复的TCP三次握手和四次挥手的环节。

二、TCP之KeepAlive详解

2.1 为什么需要KeepAlive?

广叔:你前面说的有点浅,忽悠小白还可以,想忽悠我们那个大胖子领导,还是不行呀,我先说说我对TCP知识的理解吧,你看看下边这个图,就是在TCP层发出一个请求,然后。。(打断)

令狐冲:停!首先要明确的是在TCP层是没有“请求”一说的,TCP是一种通信的方式,“请求”一词是事务上的概念,HTTP协议是一种事务协议,如果说发送一个HTTP请求,这种说法就没有问题。

广叔:我去,之前都记得是错的呀,这次真的记住了。

令狐冲:TCP的三次握手,你还记得吧?看看下边:

**广叔:**哎呀,看了你的图,我回忆起来了,之前在学校的时候学过的~

令狐冲:那下面我通过wireshark抓取一个TCP建立握手的过程,您仔细看下。(命令行基本上用TCPdump,后面我们还会用这张图说明问题):

**令狐冲:**现在你只要看前3行,这就是TCP三次握手的完整建立过程,第一个报文SYN从发起方发出,第二个报文SYN,ACK是从被连接方发出,第三个报文ACK确认对方的SYN,ACK已经收到,是不是和上面的图我是完全对应的?

广叔:是的,但是我看数据实际上并没有传输呀,第四个报文才是数据传输开始的过程。

令狐冲:是的,wireshark把第四个报文解析成HTTP协议,HTTP协议的GET方法和URI也解析出来,所以说TCP层是没有请求的概念,HTTP协议是事务性协议才有请求的概念,TCP报文承载HTTP协议的请求(Request)和响应(Response)。

广叔:说了半天,还没说为啥需要keepAlive呢?

令狐冲:别急嘛,这就说。链接建立之后,如果应用程序或者上层协议一直不发送数据,或者隔很长时间才发送一次数据,当链接很久没有数据报文传输时如何去确定对方还在线,到底是掉线了还是确实没有数据传输,链接还需不需要保持,这种情况在TCP协议设计中是需要考虑到的。

广叔:那咋解决的呀?

令狐冲:TCP协议通过一种巧妙的方式去解决这个问题,当超过一段时间之后,TCP自动发送一个数据为空的报文给对方,如果对方回应了这个报文,说明对方还在线,链接可以继续保持,如果对方没有报文返回,并且重试了多次之后则认为链接丢失,没有必要保持链接。

广叔:这就是keepAlive?这也不难嘛~~

2.2 如何开启KeepAlive?

广叔:那KeepAlive到底是咋开启的?默认就开启了吗?

令狐冲:并不是默认开启的,在Linux系统上没有一个全局的选项去开启TCP的KeepAlive。需要开启KeepAlive的应用必须在TCP的socket中单独开启。

令狐冲:在设置keepAlive之前,我们可以看看它都支持哪些选项:
1. KeepAlive默认情况下是关闭的,可以被上层应用开启和关闭
2. tcp_keepalive_time: KeepAlive的空闲时长,或者说每次正常发送心跳的周期,默认值为7200s(2小时)
3. tcp_keepalive_intvl: KeepAlive探测包的发送间隔,默认值为75s
4. tcp_keepalive_probes: 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次)

令狐冲:在Linux中我们可以通过修改 /etc/sysctl.conf 的全局配置:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

令狐冲:添加上面的配置后输入 sysctl -p 使其生效,你可以使用 sysctl -a | grep keepalive 命令来查看当前的默认配置,当然,如果应用中已经设置SO_KEEPALIVE,程序不用重启,内核直接生效。

广叔:这么简单呀,我回头要试试~~

令狐冲:是的呀,还可以使用Java、C语言以及在Nginx设置,这里我就不一一展开了。

2.3 keepAlive的局限性

广叔:那你说这个技术这么好,为啥不是默认开启的吗?

令狐冲:哎呦,终于感觉到你的秃头可能真的有点属于聪明绝顶了,没错,tcp自带的keepalive还是有些不足之处的。

令狐冲:keepalive只能检测连接是否存活,不能检测连接是否可用。例如,某一方发生了死锁,无法在连接上进行任何读写操作,但是操作系统仍然可以响应网络层keepalive包。

广叔:这确实是个问题,我之前没有想到这一点。还有吗?

令狐冲:TCP keepalive机制依赖于操作系统的实现,灵活性不够,默认关闭,且默认的 keepalive 心跳时间是 两个小时, 时间较长。并且,代理(如socks proxy)、或者负载均衡器,会让tcp keepalive失效。

广叔:那就没有解决办法了吗?

令狐冲:办法肯定是有的呀,我们往往需要加上应用层的心跳,这个需要自己去实现,就不展开了。。

HTTP之Keep-Alive详解

3.1 http为什么需要Keep-Alive?

广叔:那你再说说为啥http也需要keep-Alive呗~~

令狐冲:通常一个网页可能会有很多组成部分,除了文本内容,还会有诸如:js、css、图片等静态资源,有时还会异步发起AJAX请求。只有所有的资源都加载完毕后,我们看到网页完整的内容。然而,一个网页中,可能引入了几十个js、css文件,上百张图片,如果每请求一个资源,就创建一个连接,然后关闭,代价是不是太大了?

广叔:嗯,确实很大,如果这些连接能够复用就好了~

令狐冲:是的,大牛们也是这样想的,他们也希望连接能够在短时间内得到复用,在加载同一个网页中的内容时,尽量的复用连接,这就是HTTP协议中keep-alive属性的作用。

广叔:那这个也是默认关闭的吗?

令狐冲:这个可不是,要看版本,HTTP的Keep-Alive是HTTP1.1中默认开启的功能。通过headers设置"Connection: close "关闭;在HTTP1.0中是默认关闭的。通过headers设置"Connection: Keep-Alive"开启。

广叔:那这个保持连接的时间是怎么确定的呢?

令狐冲:Keep-Alive属性保持连接的时间长短是由服务端决定的,通常配置都是在几十秒左右。

令狐冲:TCP连接建立之后,HTTP协议使用TCP传输HTTP协议的请求(Request)和响应(Response)数据,一次完整的HTTP事务如下图:

**令狐冲:**这张图我简化了HTTP(Req)和HTTP(Resp),实际上的请求和响应需要多个TCP报文,广叔,你从这张图中看出了啥呀?说说

广叔:从图中可以发现一个完整的HTTP事务,有链接的建立,请求的发送,响应接收,断开链接这四个过程。

令狐冲:是的,早期通过HTTP协议传输的数据以文本为主,一个请求可能就把所有要返回的数据取到,但是,现在要展现一张完整的页面需要很多个请求才能完成,如图片.JS.CSS等,如果每一个HTTP请求都需要新建并断开一个TCP,这个开销是完全没有必要的。

广叔:是的,没有必要,资源都浪费了~

令狐冲:开启HTTP Keep-Alive之后,能复用已有的TCP链接,当前一个请求已经响应完毕,服务器端没有立即关闭TCP链接,而是等待一段时间接收浏览器端可能发送过来的第二个请求,通常浏览器在第一个请求返回之后会立即发送第二个请求,如果某一时刻只能有一个链接**,同一个TCP链接处理的请求越多,开启KeepAlive能节省的TCP建立和关闭的消耗就越多。**

广叔:那直接使用一个链接不就更省资源了?

令狐冲:这。。。那和电脑只用一个CPU核调度有啥区别?所有的进程都等着这个cpu去调度吗?你分手的时候,不是还说,不能在一棵树上吊死吗?要拥抱森林来着?

令狐冲:通常会启用多个链接去从服务器器上请求资源,但是开启了Keep-Alive之后,仍然能加快资源的加载速度。HTTP/1.1之后默认开启Keep-Alive, 在HTTP的头域中增加Connection选项。当设置为Connection:keep-alive表示开启,设置为Connection:close表示关闭。

广叔:ok,我是彻底明白了。

===================================================
字节内推:
字节内推〉字节校招开启。简历砸过来!!!!!!!
200多个岗位,地点:北京 上海 广州 杭州 成都 深圳。。
有问题可以直接在公众号中回复,必回答!!!

字节内推码:B1RHWFK
官网校招简历投递通道:https://jobs.toutiao.com/campus/m/position?referral_code=B1RHWFK

===================================================
微信公众号:猿侠令狐冲

不可不知的KeepAlive科普相关推荐

  1. 推荐一个java技术文章公众号

    ☕️Java基础 2018年如何快速学Java 泛型就这么简单 注解就这么简单 Druid数据库连接池就是这么简单 Object对象你真理解了吗? JDK10都发布了,nio你了解多少? COW奶牛! ...

  2. 网络程序之TCP、UDP篇(其一)

    我记得最开始接触网络程序是在我读大二的时候,当时我做的是一个聊天的程序,也不知道服务器和客户端的概念,在网上就是一顿找啊,才到自己能看懂的答案,但是只能两个程序能聊天.造成这样的原因是程序是阻塞的,然 ...

  3. 科普丨你不得不知道的20个大数据术语

    1.算法."算法"如何与大数据相关?即使算法是一个通用术语,但大数据分析使其在当代更受青睐和流行. 2.分析.年末你可能会收到一份来自信用卡公司寄来的包含了全年所有交易记录的年终报 ...

  4. 历史or技术科普(1)unix和linux你所不知道的历史

    文章目录 UNIX 的坎坷历史 C语言的诞生 AT&T和BSD的纠纷 开源领袖斯托曼 GNU 简介 历史 Solaris 和 FreeBSD Linux 的那些往事 UNIX与Linux的亲密 ...

  5. 你可能不知道的Shell

    Shell也叫做命令行界面,它是*nix操作系统下用户和计算机的交互界面.Shell这个词是指操作系统中提供访问内核服务的程序. 这篇文章向大家介绍Shell一些非广为人知.但却实用有趣的知识,权当品 ...

  6. 系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT

    https://my.oschina.net/fdhay/blog/638631 高性能网络 | 你所不知道的TIME_WAIT和CLOSE_WAIT 2016-02-18 大房 大房说 本文是我将最 ...

  7. 亲测吃知乎月饼变身“喷射战士”,我给大家科普一下发生甚么事了

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI "泻药,人在厕所,刚下马桶." 没想到,知乎"谢邀"的谐音梗竟然成真了. 中秋将至,互联网大厂都推出 ...

  8. 「从源码中学习」面试官都不知道的Vue题目答案

    前言 当回答面试官问及的Vue问题,我们除了照本宣科的回答外,其实还可以根据少量的源码来秀一把,来体现出你对Vue的深度了解. 本文会陆续更新,此次涉及以下问题: "new Vue()做了什 ...

  9. 微服务网关 Kong 科普

    Kong 是由 Mashape 开发的并于2015年开源的一款API 网关,它是基于OpenResty(Nginx + Lua模块)和 Apache Cassandra/PostgreSQL 构建的, ...

最新文章

  1. 基于标记的AR的OpenCV实现
  2. Java 7之多线程- Semaphore--转载
  3. P3834 【模板】可持久化线段树 1(主席树)
  4. ElementTree中的getchildren and getiterator
  5. array_combine()
  6. Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)
  7. 深度学习-tensorflow1.x:平均值(reduce_mean)与求和(reduce_sum) 小白理解 代码实现 Tensorflow1.x 和 Numpy
  8. 三分钟快速理解javascript内存管理
  9. 有趣的算法(八):3分钟看懂选择排序(C语言实现)
  10. Golang-PKCS8
  11. 为资产分类定义折旧范围_SAP折旧范围
  12. Codeforces 1180B
  13. Win10搭建gym运行atari游戏pong
  14. [Python人工智能] 四.神经网络和深度学习入门知识
  15. golang学习(三)—— 数组、切片、map
  16. P4147 玉蟾宫 题解
  17. 两码一号(九):业务监控
  18. MySQL自动删除指定时间以前的记录
  19. 用计算机说早上好,早上好的问候语简短 高情商会说的60句早安
  20. 技巧篇:常用的python代码汇总

热门文章

  1. 【SpringCloud】微服务笔记
  2. 数论:欧几里得与扩展欧几里得算法
  3. 使用GRUB2制作多重系统引导程序
  4. python KS-检验(Kolmogorov-Smirnov test) -- 检验数据是否符合某种分布
  5. Vim 匹配相同的单词并高亮
  6. Git分支的创建,切换及分支指针移动的理解
  7. java 处理unicode_[转]Java的Unicode编码转化(多种情况处理方法)
  8. netstat 的各个 state 什么意思
  9. 多元统计分析——数据降维——因子分析(FA)
  10. 数据库并发入门学习笔记,怎么写入redis的数据,配置缓存。