如何确定这些Linux TCP默认设置?


13

最近,我花了相当多的时间来查找生产中的问题,其中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探针极为ing。AIUI,默认tcp_keepalive_time值为2小时,这意味着当我们等待远程主机的响应时,我们将耐心等待2小时,然后再发起一次keepalive探测以验证我们的连接仍然有效。然后,如果远程主机不响应keepalive探测,则我们将对这些keepalive探测重试9次(tcp_keepalive_probes),相隔75秒(tcp_keepalive_intvl),因此,在我们确定连接真正失效之前,还需要再花11分钟。

这与我在该字段中看到的内容相符:例如,如果我启动一个psql连接到远程PostgreSQL实例的会话,并且有一些查询等待响应,例如

SELECT pg_sleep(30);

然后使远程服务器严重死亡(例如,丢弃该机器的流量),我发现我的psql会话等待长达2个小时11分钟才能发现连接已死。您可能会想到,这些默认设置会对我们在数据库故障转移事件期间与数据库交谈的代码造成严重问题。调低这些旋钮很有帮助!而且我发现我并不孤单地建议调整这些默认值。

所以我的问题是:

  • 这样的默认设置多长时间了?
  • 使这些TCP设置成为默认设置的最初理由是什么?
  • 有任何Linux发行版会更改这些默认值吗?

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



请注意,您可以更改客户端代码与套接字选项前三每个连接TCP_KEEPIDLETCP_KEEPCNTTCP_KEEPINTVL
wnoise

1
实际上,从Linux 2.6.37开始,@ wnoise 也应该也可以指定套接字选项TCP_USER_TIMEOUT,而不是在net.ipv4.tcp_retries2系统范围内进行设置。当然,许多应用程序(例如我的示例中的PostgreSQL)尚不支持TCP_USER_TIMEOUT
Josh Kupershmidt 2015年

Answers:


6

RFC 1122在4.2.3.6节中规定,保活期不得默认为少于两个小时。


1
很好,谢谢您对此进行了深入研究。我认为这基本上回答了为什么tcp_keepalive_time默认为7200 的问题,尽管我仍然对其他三个相关设置的先例/解释感兴趣。
Josh Kupershmidt

删除我的答案,因为这可以回答问题(至少是其中一个值)
coteyr

1
@coteyr无论如何,谢谢,我非常感谢。IIRC对您的回答有一个有趣的评论,表明在较早的Linux内核中,默认值为15分钟。我会对如何/为什么将其更改为2小时,或者首先将其设置为15分钟感兴趣。
Josh Kupershmidt 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.