Answers:
最大连接数受客户端和服务器端的某些限制的影响,尽管有所不同。
在客户端:
增大外围端口范围,并减小tcp_fin_timeout
要找出默认值:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
外围端口范围定义了主机可以从特定IP地址创建的最大出站套接字数。所述fin_timeout
定义的最小时间这些插座会留在TIME_WAIT
状态(在使用一次后无法使用)。通常的系统默认值为:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
这基本上意味着您的系统无法始终保证(61000 - 32768) / 60 = 470
每秒提供更多的套接字。如果您对此不满意,可以先增加port_range
。如今,将范围设置15000 61000
为相当普遍。您可以通过降低来进一步提高可用性fin_timeout
。假设您同时执行了这两项操作,则应该更容易地看到每秒超过1500个出站连接。
更改值:
sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
以上内容不应解释为影响系统每秒进行出站连接的能力的因素。但是,这些因素会影响系统在长时间的“活动”中以可持续的方式处理并发连接的能力。
默认sysctl的参数上一个典型的Linux箱tcp_tw_recycle
和tcp_tw_reuse
会
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
这些不允许来自“已用”套接字的连接(处于等待状态),并强制套接字持续整个time_wait
周期。我建议设置:
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
这样可以快速切换套接字的time_wait
状态并重新使用它们。但是,在进行此更改之前,请确保这与用于这些套接字的应用程序所使用的协议不冲突。确保阅读Vincent Bernat的文章“应对TCP TIME-WAIT”以了解其含义。对于net.ipv4.tcp_tw_recycle
面向公众的服务器,该选项存在很大问题,因为它无法处理来自同一NAT设备后面的两台不同计算机的连接,这是一个很难检测并等待您咬下去的问题。请注意,net.ipv4.tcp_tw_recycle
它已从 Linux 4.12中删除。
在服务器端:
该net.core.somaxconn
值具有重要的作用。它限制了排队到侦听套接字的最大请求数。如果您确定服务器应用程序的功能正常,请将其从默认的128提高到128到1024。现在,您可以通过将应用程序的listen调用中的listen backlog变量修改为相等或更大的整数来利用此增加。
sysctl net.core.somaxconn=1024
txqueuelen
以太网卡的参数也可以发挥作用。默认值为1000,因此如果系统可以处理,则将其提高到5000甚至更高。
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
类似地增加极值net.core.netdev_max_backlog
和net.ipv4.tcp_max_syn_backlog
。它们的默认值分别是1000和1024。
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
现在,请记住通过增加外壳中的FD ulimts来启动客户端和服务器端应用程序。
除上述以外,程序员使用的另一种比较流行的技术是减少tcp写调用的次数。我自己的偏好是使用一个缓冲区,在该缓冲区中,我将希望发送的数据推送到客户端,然后在适当的时候,将缓冲的数据写出到实际的套接字中。这种技术使我可以使用大数据包,减少碎片并降低用户域和内核级的CPU使用率。
(61000 - 32768) / 60 = 470 sockets per second
。您能详细说明一下吗?
有几个变量可以设置最大连接数。最有可能的是,您首先用尽了文件编号。检查ulimit -n。之后,/ proc中有一些设置,但这些默认设置为成千上万。
更重要的是,听起来您做错了什么。一个TCP连接应该能够使用两方之间的所有带宽。如果不是:
ping -s 1472
...)tc
iperf
可能我误会了。也许您正在做类似Bittorrent的事情,您需要大量的连接。如果是这样,您需要找出您实际使用了多少个连接(尝试netstat
或lsof
)。如果该数目很大,您可以:
ulimit -n
。尽管如此,〜1000个连接(我的系统上的默认连接)还是很多。iostat -x
吗?另外,如果您使用的是消费级NAT路由器(Linksys,Netgear,DLink等),请注意,成千上万的连接可能会超出其功能。
我希望这会有所帮助。您实际上是在问网络问题。
为了改善derobert的回答,
您可以通过设置nf_conntrack_max来确定操作系统的连接限制。
例如:cat / proc / sys / net / netfilter / nf_conntrack_max
您可以使用以下脚本来计算到给定范围的tcp端口的tcp连接数。默认情况下为1-65535。
这将确认您是否正在使操作系统连接限制最大化。
这是脚本。
#!/bin/bash
OS=$(uname)
case "$OS" in
'SunOS')
AWK=/usr/bin/nawk
;;
'Linux')
AWK=/bin/awk
;;
'AIX')
AWK=/usr/bin/awk
;;
esac
netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
if ($1 ~ /\./)
{sip=$1}
else {sip=$4}
if ( sip ~ /:/ )
{d=2}
else {d=5}
split( sip, a, /:|\./ )
if ( a[d] >= start && a[d] <= end ) {
++connections;
}
}
END {print connections}'
which awk
是您确定awk路径的朋友,SunOS也有一个链接:)
which
依靠该程序,而无需提供完整路径。(也就是说,我不确定脚本中的解决方案是否更接近完美,但这不是脚本所要解决的问题)。PATH
awk
awk
位置,但是假设shell始终是/bin/bash
(提示:AIX5 / 6在默认情况下甚至没有bash)。
awk
检测有用吗?个人而言,我会简单地假设有一个正确的PATH
,但一个合理的选择可能是/usr/bin/env awk
和/usr/bin/env bash
分别。对于它的价值,它在我的Linux系统上位置错误。它在/usr/bin/awk
不/bin/awk
在应用程序级别,开发人员可以执行以下操作:
从服务器端:
检查负载均衡器(如果有)是否正常工作。
将缓慢的TCP超时转换为503快速立即响应,如果负载均衡器正常工作,则应选择要使用的工作资源,这比在发生意外错误消息时挂在那里要好。
例如:如果您使用的是节点服务器,那么您可以从npm使用太忙。实现类似:
var toobusy = require('toobusy');
app.use(function(req, res, next) {
if (toobusy()) res.send(503, "I'm busy right now, sorry.");
else next();
});
为什么是503?以下是有关过载的一些很好的见解:http : //ferd.ca/queues-don-t-fix-overload.html
我们也可以在客户端做一些工作:
尝试将呼叫分组,减少客户端和服务器的流量和总请求数。
尝试构建缓存中间层以处理不必要的重复请求。