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

Jos*_*idt 13 linux history tcp

我最近花了很多时间来跟踪生产中的一个问题,数据库服务器消失会导致poll()连接的客户端挂起长达 2 小时(长时间等待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 内核默认值没有变化。

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

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

SELECT pg_sleep(30);

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

所以我的问题是:

  • 默认设置这样多久了?
  • 将这些 TCP 设置设为默认设置的最初理由是什么?
  • 是否有任何 Linux 发行版更改了这些默认值?

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

wno*_*ise 6

RFC 1122在第 4.2.3.6 节中指定保活期不得默认少于两小时。