tcp KeepAlive vs http KeepAlive

1. 写在最前面

这个问题的好奇点背景是这个样子的。

笔者所在的公司到了一年一度换证书的日子,为了做 double check (嗯,其实就是作为弱鸡的我默默的围观大佬换证书)。在验证更换证书是否生效的时候,有一个很有趣的现象:

用之前已经打开的 Google 页面刷新的话,证书还是 2020 年的。

用新打开的隐私窗口验证的话,证书就变成 2021 年的。

作为一名资深好奇宝宝,我就开始十分好奇这到底是什么原因导致的?

答案:哎,其实很简单,因为 HTTP 1.1 协议以后默认是开启 KeepAlive 。而 https = http + tls + tcp, client 和 server 只会在 tcp 连接创建成功以后会进行一次 tls 握手,从 server 端获取证书信息。这就解释了为什么「用之前已经打开的 Google 页面刷新的话,不会获取到新证书」

注:维基百科——http持久连接 在 HTTP 1.1 中所有的连接默认都是持续连接,除非特殊声明不支持。

反正好奇都好奇了,那不如就多好奇一点吧。比如 tcp 和 http 的 KeepAlive 有啥区别。

2. 两种 KeepAlive 的区别

先说结论,这压根是两个概念。

  • http 协议的 KeepAlive 目的在于连接复用,同一个连接上串行方式传递请求 - 响应数据
  • 协议的 KeepAlive 目的在于保活、心跳,检测连接错误。

3. 验证 KeepAlive

3.1 http KeepAlive

以www.zhihu.com 的网址为例。

注: 为了确保「知乎」的地址解析到同一个 ip 地址,笔者在测试之前已增加的记录

112.65.212.141 www.zhihu.com

一图胜过千文,笔者抓了四类包:

  • tcp 三次握手的包
  • tls 1.3 协商密钥的包
  • tcp keep alive 探测 tcp 连接可用性的包
  • 以及等待一定时间内刷新页面重新请求知乎接口的包

在这里插入图片描述

3.1.1 结论

  • 确实没有重新进行 tls 握手,这就解释了为什么下发新证书后,刷新页面没有获取到最新的证书信息。

  • 那么如何手动让浏览器关闭活跃的 tcp 连接呢?

    在这里插入图片描述

思考:如果用 curl 请求是不是需要每次都重新进行 tls 呢?

3.2 tcp KeepAlive

tcp KeepAlive 并不是 tcp 协议的一部分,但是大多数操作系统都实现了这个机制。KeepAlive 机制可以理解为:

  • 在「指定时间」内,tcp 链路上没有数据传送的情况下,tcp 层将发送相应的 KeepAlive 探针以确定连接可用性
  • 探针失败后将会在「指定时间间隔」内重试,探测最多「指定失败次数」
  • 所有探测失败后,即认为当前连接已经不可用。
net.ipv4.tcp_keepalive_intvl=20 -> 指定时间间隔
net.ipv4.tcp_keepalive_probes=3 -> 指定失败次数
net.ipv4.tcp_keepalive_time=60 -> 指定时间

注:上述配置即可翻译为在 60s 内,tcp 层没有数据传输的情况下,系统内核将发送 tcp KeepAlive 的探针以确定连接可用性,每次间隔 20s,最多探测失败 3 次,即认为该 tcp 连接不可用。

3.2.1 结论

  • tcp KeepAlive 的配置参数是在操作系统上设置的,对不在同一台机器上部署的不同应用来说不够灵活
  • 操作系统内核探测 tcp 连接是否可用不具有实时性,比如,连接已经在探测的间隔内断掉了,但是须在连续多次探测失败后才上报连接不可用

4. 碎碎念

2020 就这么一去不复返啦,你也一定有很多遗憾吧?不要急,走的慢但是也走的稳一点。2021 也请你一定要继续、继续加油哦。

  • 不要为了捍卫标准而捍卫标准,那是学界的事,工程永远都是实用主义优先。
  • 要按照自己喜欢的节奏来,不看别人,心就不会慌,东张西望的,容易摔倒。

5. 参考资料

猜你喜欢

转载自blog.csdn.net/phantom_111/article/details/111567773
今日推荐