题 什么限制了Linux服务器上的最大连接数?


什么内核参数或其他设置控制可以在Linux服务器上打开的最大TCP套接字数?允许更多连接的权衡是什么?

我注意到在加载测试Apache服务器时 AB 最大化服务器上​​的开放连接非常容易。如果你不使用ab的-k选项,它允许连接重用,并让它发送超过10,000个请求,那么Apache服务前11,000个左右的请求,然后停止60秒。查看netstat输出显示TIME_WAIT状态下的11,000个连接。显然,这是正常的。即使在客户端完成连接之后,连接仍保持打开默认值60秒 TCP可靠性原因

看起来这对于DoS服务器来说是一种简单的方法,我想知道通常的调整和预防措施是什么。

这是我的测试输出:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

这是我在测试期间运行的netstat命令:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab

85
2018-05-21 16:18






答案:


我终于找到了真正限制连接数的设置: net.ipv4.netfilter.ip_conntrack_max。这被设置为11,776,无论我设置的是我在测试之前可以在等待之前提供的请求数 tcp_fin_timeout 更多连接可用的秒数。该 conntrack table是内核用来跟踪连接状态的,所以一旦它满了,内核就会开始丢弃数据包并在日志中打印出来:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

下一步是让内核回收所有这些连接 TIME_WAIT 状态而不是丢弃数据包。我可以通过打开来实现这一点 tcp_tw_recycle 或增加 ip_conntrack_max 大于可用于连接的本地端口数 ip_local_port_range。我猜一旦内核超出本地端口,就会开始回收连接。这使用了更多的内存跟踪连接,但它似乎是比开启更好的解决方案 tcp_tw_recycle 因为文档暗示这是危险的。

通过这种配置,我可以整天运行ab并且永远不会用完连接:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

tcp_max_orphans 设置对我的测试没有任何影响,我不知道为什么。我认为它会关闭连接 TIME_WAIT 状态一旦有8192,但它不适合我。


62
2018-06-03 16:02



我们在哪里配置这些参数? - Codevalley
@Codevalley这可能是系统相关的,但在Ubuntu Server上它们位于/etc/sysctl.conf - Ben Williams


您真的想看看/ proc文件系统在这方面为您提供的内容。

在最后一页上,您可能会发现以下内容对您感兴趣:


23
2018-05-21 18:15



tcp_max_orphans很有趣但看起来它不起作用。当我在测试期间尝试测量孤立套接字时,我看到11,651个,而tcp_max_orphans是8,092。 #netstat --inet -p | grep“localhost:www”| sed -e's / \ + / / g'| cut -d'' - f 1-4,6-7 |排序| uniq -c 11651 tcp 0 0 localhost:www TIME_WAIT - - Ben Williams
看看tcp_orphan_retries设置 - 想法是,套接字被“剔除”更快...... - Avery Payne
@Jauder Ho的建议+ tcp_orphan_retries听起来像你的情况的潜在胜利。 - Avery Payne


我不认为有一个可调参数可以直接设置。这属于TCP / IP调整类别。要找出你可以调整的内容,请尝试'man 7 tcp'。 sysctl('man 8 sysctl')用于设置这些。 'sysctl -a | grep tcp'将向您显示您可以调整的大部分内容,但我不确定它是否会显示所有内容。此外,除非已更改,否则打开的TCP / IP套接字看起来像文件描述符。所以 这个 并且该链接的下一部分可能就是您要找的内容。


3
2018-05-21 17:31





尝试设置以下设置以及设置tcp_fin_timeout。这应该更快地关闭TIME_WAIT。

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

2
2018-05-21 19:38



小心点!经历了艰难的经历。 “这可能会导致带有负载平衡和NAT的丢帧,只能将其用于仅通过本地网络进行通信的服务器。” - wiki.archlinux.org/index.php/Sysctl - Henk
@Henk我想是的 tcp_tw_recycle 这是有潜在危险的。 tcp_tw_reuse 更安全,我没有看到任何理由同时使用它们。 - Vladislav Rastrusny


库存apache(1)过去预定义只支持250个并发连接 - 如果你想要更多,有一个头文件需要修改以允许更多的并发会话。我不知道Apache 2是否仍然如此。

此外,您需要添加一个选项,以允许运行Apache的帐户加载更多打开的文件描述符 - 这是之前的注释未指出的内容。

注意你的工作人员设置以及你在Apache内部有多少保持活动超时,你一次运行多少个备用服务器,以及这些额外进程被杀死的速度有多快。


2
2018-05-21 21:21





您可以减少在TIME_WAIT状态下花费的时间(设置net.ipv4.tcp_fin_timeout)。 您可以用YAWS或nginx或类似的东西替换Apache。

更多连接的权衡通常涉及内存使用,如果你有一个分叉过程,许多子进程会占用你的CPU。


1
2018-05-21 16:26



tcp_fin_timeout不用于设置TIME-WAIT到期,这在重建内核之外是不可更改的,但对于FIN,如名称所示。 - Alexandr Kurilin


可以在单个IP地址上打开的套接字的绝对数量是2 ^ 16,由TCP / UDP而不是内核定义。


0
2018-05-30 16:42



不,不是。您可以打开更多,因为只要远程地址不同,本地端口就不需要是唯一的。此外,OP表示每台服务器,每台服务器可以有> 1个地址。 - MarkR


Apache HTTP服务器基准测试工具, AB,在2.4版本中有 -s timeout 选项。也可以看看 ab(Apache Bench)错误:apr_poll:指定的超时在Windows上已过期(70007)

此选项可以解决您的问题。


0
2018-02-08 17:56