哪些内核参数或其他设置控制 Linux 服务器上可以打开的 TCP 套接字的最大数量?允许更多连接的权衡是什么?
我在对 Apache 服务器进行负载测试时注意到AB很容易使服务器上的打开连接达到最大值。如果您不使用 ab 的 -k 选项(允许连接重用),并让其发送超过 10,000 个请求,那么 Apache 将处理前 11,000 个左右的请求,然后暂停 60 秒。查看 netstat 输出显示 11,000 个连接处于 TIME_WAIT 状态。显然,这是正常的。即使客户端使用完这些连接,连接仍默认保持打开状态 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
答案1
我终于找到了真正限制连接数的设置: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.
下一步是让内核回收处于该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 个连接,它就会关闭状态中的连接,但它并没有为我这样做。
答案2
您确实想看看 /proc 文件系统在这方面能为您提供什么。
在最后一页,您可能会发现以下内容会引起您的兴趣:
- /proc/sys/net/ipv4/tcp_max_orphans,控制系统所持有的最大套接字数量不是附加到某物上。增加此值可能会消耗多达 64kbyte 的不可交换内存每个孤立套接字。
- /proc/sys/net/ipv4/tcp_orphan_retries,它控制套接字变为孤立并关闭之前的重试次数。 该页面上有一个关于 Web 服务器的具体说明,与您直接相关……
答案3
我认为没有可以直接设置的可调参数。这属于 TCP/IP 调整类别。要了解可以调整的内容,请尝试“man 7 tcp”。sysctl(“man 8 sysctl”)用于设置这些。“sysctl -a | grep tcp”将显示您可以调整的大部分内容,但我不确定它是否会显示所有内容。此外,除非这种情况发生变化,否则 TCP/IP 套接字打开后看起来像文件描述符。因此这该链接中的下一部分可能就是您正在寻找的内容。
答案4
现有的 apache(1) 预定义仅支持 250 个并发连接 - 如果您需要更多,则需要修改一个头文件以允许更多并发会话。我不知道 Apache 2 是否仍然如此。
此外,您还需要添加一个选项,以允许为运行 Apache 的帐户加载更多打开的文件描述符 - 这是之前的评论未能指出的。
注意你的工作进程设置以及 Apache 内部的保持活动超时类型、你同时运行的备用服务器数量以及这些额外进程被终止的速度。