在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_recycletcp_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_backlognet.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上,这是使用tcconfiguration的
  • 确认您认为存在的带宽实际上是否存在,例如使用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}' 

在应用程序级别,开发人员可以这样做:

从服务器端:

  1. 检查负载均衡器(如果有),工作正常。

  2. 将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

我们也可以在客户端做一些工作:

  1. 尝试批量分组呼叫,减less客stream量和服务器的stream量和总请求数量。

  2. 尝试build立一个caching中层来处理不必要的重复请求。