这些 Linux TCP 默认设置是如何决定的?

这些 Linux TCP 默认设置是如何决定的?

最近,我花了相当多的时间来追踪生产中的一个问题,其中数据库服务器消失会导致连接的客户端挂起长达 2 小时(poll()在 libpq 客户端库中等待调用的时间很长)。深入研究这个问题,我意识到应该向下调整这些内核参数,以便及时注意到断开的 TCP 连接:

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

上面的四个值来自 Ubuntu 12.04 机器,看起来这些默认值与当前版本没有变化Linux 内核默认值

这些设置似乎严重偏向于保持现有连接打开,并且对保活探针极其吝啬。 AIUI,默认tcp_keepalive_time2小时意味着当我们等待远程主机的响应时,我们将耐心等待2小时,然后启动keepalive探测以验证我们的连接是否仍然有效。然后,如果远程主机没有响应保活探测,我们会重试这些保活探测 9 次 ( tcp_keepalive_probes),间隔 75 秒 ( tcp_keepalive_intvl),因此在我们确定连接确实已断开之前,需要额外等待 11 分钟。

这与我在现场看到的相符:例如,如果我启动一个psql连接到远程 PostgreSQL 实例的会话,其中一些查询正在等待响应,例如

SELECT pg_sleep(30);

然后让远程服务器可怕地死掉(例如,该机器的流量下降),我看到我的 psql 会话等待了长达 2 小时 11 分钟,然后才发现它的连接已死。正如您可能想象的那样,这些默认设置会导致我们在数据库故障转移事件期间与数据库通信的代码出现严重问题。调低这些旋钮有很大帮助!我发现我是不孤单建议调整这些默认值。

所以我的问题是:

  • 这种默认状态已经持续多久了?
  • 将这些 TCP 设置设为默认设置的最初理由是什么?
  • Linux 发行版是否更改了这些默认值?

对于这些设置的基本原理的任何其他历史或观点将不胜感激。

答案1

RFC 1122第 4.2.3.6 节中指定保持活动时间不得默认小于两个小时。

相关内容