在Linux中增加最大数量的tcp / ip连接
我正在编程一个服务器,好像我的连接数目是有限的,因为我的带宽没有饱和,即使我已经设置连接数为“无限”。
如何增加或消除我的Ubuntu Linux可以同时打开的最大数量的连接? 操作系统是限制这个,还是路由器或ISP? 或者是别的什么?
连接的最大数量受到客户端和服务器端的某些限制的影响,尽pipe有些不同。
在客户端:增加ephermal端口范围,并减lesstcp_fin_timeout
要找出默认值:
sysctl net.ipv4.ip_local_port_range sysctl net.ipv4.tcp_fin_timeout
ephermal端口范围定义主机可以从特定IP地址创build的出站套接字的最大数量。 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
是很常见的。 您可以通过减lessfin_timeout
来进一步提高可用性。 假设你们都这么做,你应该更容易地看到每秒超过1500个出站连接。
要更改这些值:
sysctl net.ipv4.ip_local_port_range="15000 61000" sysctl net.ipv4.tcp_fin_timeout=30
以上不应被解释为影响每秒进行出站连接的系统能力的因素。 而是这些因素影响系统处理并发连接的能力,以可持续的方式进行大量的“活动”。
默认Sysctl值在tcp_tw_recycle
& tcp_tw_reuse
的典型linux tcp_tw_reuse
上
net.ipv4.tcp_tw_recycle=0 net.ipv4.tcp_tw_reuse=0
这些不允许来自“使用的”套接字(处于等待状态)的连接并强制套接字持续完整的time_wait
周期。 我build议设置:
sysctl net.ipv4.tcp_tw_recycle=1 sysctl net.ipv4.tcp_tw_reuse=1
这允许在等待状态下快速循环sockets并重新使用它们。 但是在你做这个改变之前,请确保这与你需要这些套接字的应用程序使用的协议不冲突。
在服务器端: net.core.somaxconn
值有重要的作用。 它限制排队到侦听套接字的最大请求数。 如果您确信自己的服务器应用程序的function,将其从默认128提升到128到1024之间。现在,您可以通过将应用程序的监听调用中的listen backlogvariables修改为相等或更高的整数来利用此增加。
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
现在请记住通过在shell中增加FD ulimts来启动客户端和服务器端应用程序。
除了上面提到的程序员使用的更stream行的技术是减lesstcp写入调用的次数。 我自己的select是使用一个缓冲区,在这个缓冲区中,我将要发送给客户端的数据按下,然后在适当的位置将缓冲的数据写入到实际的套接字中。 这种技术使我可以使用大量的数据包,减less碎片,降低我在内核级用户的CPU利用率。
有几个variables来设置最大连接数。 最有可能的是,你首先用完了文件号码。 检查ulimit -n。 之后,/ proc中有设置,但是默认为数万。
更重要的是,这听起来像你做错了什么。 单个TCP连接应该能够使用双方之间的所有带宽; 如果不是:
- 检查你的TCP窗口设置是否足够大。 除了真正快速的inet链接(数百mbps)或快速的卫星链接之外,Linux的默认设置对所有应用都是有利的。 什么是你的带宽延迟产品?
- 使用大数据包
ping -s 1472
检查数据包丢失(ping -s 1472
…) - 检查速率限制。 在Linux上,这是使用
tc
configuration的 - 确认您认为存在的带宽实际上是否存在,例如使用
iperf
- 确认你的协议是正常的。 记住延迟。
- 如果这是一个千兆以太网局域网,您可以使用巨型数据包吗? 你是?
可能我误解了。 也许你正在做类似Bittorrent的事情,你需要很多的连接。 如果是这样,你需要弄清楚你实际使用了多less连接(试试netstat
或者lsof
)。 如果这个数字很大,你可能会:
- 有很多带宽,例如100mbps +。 在这种情况下,您可能实际上需要修改
ulimit -n
。 不过,〜1000个连接(在我的系统上是默认的)是不less的。 - 有networking问题,这会减慢你的连接(例如,丢包)
- 有其他的东西让你放慢速度,比如IO带宽,特别是如果你正在寻求。 你检查过
iostat -x
吗?
此外,如果您使用的是消费级NAT路由器(Linksys,Netgear,DLink等),请注意,您可能会通过数千个连接超出其function。
我希望这能提供一些帮助。 你真的在问networking问题。
为了改进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}'
在应用程序级别,开发人员可以这样做:
从服务器端:
-
检查负载均衡器(如果有),工作正常。
-
将TCP超时缓慢转换为503快速立即响应,如果你负载均衡器正常工作,它应该select工作资源来服务,它比悬挂在那里与意外的错误信息更好。
例如:如果你正在使用节点服务器,你可以使用从npm toobusy。 执行如下所示:
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
我们也可以在客户端做一些工作:
-
尝试批量分组呼叫,减less客stream量和服务器的stream量和总请求数量。
-
尝试build立一个caching中层来处理不必要的重复请求。