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


89

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

我注意到在使用ab对Apache服务器进行负载测试时,最大化服务器上​​的打开连接非常容易。如果您取消了ab的-k选项,该选项允许连接重用,并使其发送大约10,000个以上的请求,则Apache会处理大约11,000个左右的请求,然后暂停60秒钟。查看netstat输出显示TIME_WAIT状态下有11,000个连接。显然,这很正常。出于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

这是我在测试期间运行的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

Answers:


64

我终于找到了真正限制连接数量的设置: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个连接就可以关闭状态连接,但对我而言却不行。


3
我们在哪里配置这些参数?
Codevalley 2011年

2
@Codevalley可能与系统有关,但是在Ubuntu Server上,它们位于/etc/sysctl.conf
Ben Williams

24

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

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


tcp_max_orphans很有趣,但似乎无法正常工作。当我在测试过程中尝试测量孤立套接字时,我看到其中有11651个,而tcp_max_orphans是8092个。#netstat --inet -p | grep“ localhost:www” | sed -e's / \ + / / g'| 切-d''-f 1-4,6-7 | 排序| uniq的-c 11651 TCP 0 0本地主机:WWW TIME_WAIT -
本·威廉姆斯

看一下tcp_orphan_retries设置-想法是,套接字“被淘汰”更快……
艾利·佩恩

@Jauder Ho的建议+ tcp_orphan_retries听起来很适合您的情况。
艾利·佩恩

3

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


2

尝试设置以下内容以及设置tcp_fin_timeout。这样可以更快地关闭TIME_WAIT。

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

小心点!经历过艰辛的路。“这可能会导致带有负载平衡和NAT的帧丢失,仅将其用于仅通过本地网络进行通信的服务器。” - wiki.archlinux.org/index.php/Sysctl
亨克

@Henk我想tcp_tw_recycle那是潜在的危险。tcp_tw_reuse更安全,我看不到任何同时使用它们的理由。
弗拉迪斯拉夫·拉斯特鲁尼2012年

2

stock apache(1)曾经预定义为仅支持250个并发连接-如果您需要更多,可以修改一个头文件以允许更多并发会话。我不知道Apache 2是否仍然适用。

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

请注意您的工作程序设置以及Apache本身内部有哪些类型的keepalive超时,一次运行了多少个备用服务器以及这些多余的进程被杀死的速度。


1

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

更多连接的折衷通常涉及内存使用情况,如果您有派生进程,则许多子进程会淹没您的CPU。


1
tcp_fin_timeout不是用于设置TIME-WAIT到期时间,该时间在重建内核之外不可更改,而是用于FIN(顾名思义)。
亚历山德鲁·库里林

0

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


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

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.