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

Ben*_*ams 96 linux performance tuning scaling apache-2.2

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

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

这似乎是对服务器进行 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
Run Code Online (Sandbox Code Playgroud)

这是我在测试期间运行的 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
Run Code Online (Sandbox Code Playgroud)

Ben*_*ams 68

我终于找到了真正限制连接数的设置:net.ipv4.netfilter.ip_conntrack_max. 这被设置为 11,776,无论我将其设置为什么,都是我在测试中可以提供的请求数,然后必须等待tcp_fin_timeout几秒钟才能获得更多连接可用。该conntrack表是内核用来跟踪连接状态的内容,因此一旦它已满,内核就会开始丢弃数据包并将其打印在日志中:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.
Run Code Online (Sandbox Code Playgroud)

下一步是让内核在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
Run Code Online (Sandbox Code Playgroud)

tcp_max_orphans设置对我的测试没有任何影响,我不知道为什么。我认为TIME_WAIT一旦有 8192 个连接,它就会关闭state 中的连接,但它对我来说不是这样。

  • 我们在哪里配置这些参数? (3认同)
  • @Codevalley 这可能取决于系统,但在 Ubuntu Server 上,它们位于 /etc/sysctl.conf (3认同)

Ave*_*yne 24

您真的很想看看 /proc 文件系统在这方面为您提供了什么。

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

  • /proc/sys/net/ipv4/tcp_max_orphans,它控制系统持有的连接到某物的最大套接字数。提高这个值可以为每个孤立套接字消耗多达 64kbyte 的不可交换内存。
  • /proc/sys/net/ipv4/tcp_orphan_retries,它控制套接字孤立和关闭之前的重试次数。 该页面上有一个关于您直接感兴趣的 Web 服务器的特定说明...