增加linux中tcp / ip连接的最大数量

时间:2009-01-04 07:35:47

标签: linux linux-kernel

我正在编程服务器,似乎我的连接数量有限,因为即使我将连接数设置为“无限制”,我的带宽也没有饱和。

如何增加或消除我的Ubuntu Linux盒一次可以打开的最大连接数?操作系统是否限制了这个,还是路由器或ISP?或者是别的什么?

4 个答案:

答案 0 :(得分:340)

最大连接数受到客户端和客户端的某些限制的影响。服务器方面,虽然有点不同。

在客户端: 增加ephermal端口范围,并减少tcp_fin_timeout

找出默认值:

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout

ephermal端口范围定义了主机可以从特定的I.P.创建的最大出站套接字数。地址。 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

上述内容不应被解释为影响每秒进行出站连接的系统功能的因素。但是,这些因素会影响系统在大量“活动”中以可持续方式处理并发连接的能力。

tcp_tw_recycle&的典型Linux机器上的默认Sysctl值tcp_tw_reuse将是

net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0

这些不允许来自“used”套接字的连接(处于等待状态)并强制套接字持续完整的time_wait周期。我建议设置:

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

这允许在time_wait状态下快速循环套接字并重新使用它们。但在进行此更改之前,请确保这与您用于需要这些套接字的应用程序的协议不冲突。请务必阅读帖子"Coping with the TCP TIME-WAIT" from Vincent Bernat以了解其含义。 net.ipv4.tcp_tw_recycle 选项对于面向公众的服务器来说非常有问题,因为它不会处理来自同一NAT设备后面的两台不同计算机的连接,这是一个难以检测并等待咬的问题您。请注意,来自Linux4.12的net.ipv4.tcp_tw_recycle已为removed

在服务器端: 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_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来启动客户端和服务器端应用程序。

除此之外,程序员使用的一种更流行的技术是减少 tcp write 调用的次数。我自己的偏好是使用一个缓冲区,其中我将我希望发送的数据推送到客户端,然后在适当的点我将缓冲的数据写入实际的套接字。这种技术允许我使用大数据包,减少碎片,降低我在用户区和内核级别的CPU利用率。

答案 1 :(得分:57)

有几个变量可以设置最大连接数。最有可能的是,你首先没有文件编号。检查ulimit -n。之后,/ proc中有设置,但默认为数万个。

更重要的是,听起来你做错了什么。单个TCP连接应该能够使用双方之间的所有带宽;如果不是:

  • 检查TCP窗口设置是否足够大。除了真正快速的inet链路(数百mbps)或快速卫星链路之外,Linux默认设置适用于所有设备。你的带宽*延迟产品是什么?
  • 使用大数据包ping(ping -s 1472 ...)
  • 检查数据包丢失
  • 检查速率限制。在Linux上,这是使用tc
  • 配置的
  • 使用例如iperf
  • 确认您认为存在的带宽确实存在
  • 确认您的协议是正确的。记住延迟。
  • 如果这是千兆+局域网,你可以使用巨型数据包吗?你呢?

可能我误解了。也许你正在做类似Bittorrent的事情,你需要很多连接。如果是这样,您需要确定实际使用的连接数(尝试netstatlsof)。如果该数字很大,您可以:

  • 拥有大量带宽,例如100mbps +。在这种情况下,您实际上可能需要向上ulimit -n。不过,大约有1000个连接(我的系统默认)很多。
  • 网络问题导致连接速度变慢(例如数据包丢失)
  • 让别人放慢速度,例如IO带宽,特别是如果你正在寻找。你检查过iostat -x

此外,如果您使用的是消费级NAT路由器(Linksys,Netgear,DLink等),请注意您可能会通过数千个连接超出其能力。

我希望这能提供一些帮助。你真的在问网络问题。

答案 2 :(得分:15)

要改进derobert给出的答案,

您可以通过捕获nf_conntrack_max来确定您的操作系统连接限制。

例如:     cat / proc / sys / net / netfilter / nf_conntrack_max

您可以使用以下脚本来计算到给定范围的tcp端口的tcp连接数。默认1-65535。

这将确认您是否最大化了OS连接限制。

这是剧本。

#!/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}'

答案 3 :(得分:10)

在应用程序级别,开发人员可以执行以下操作:

从服务器端:

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

  2. 将慢速TCP超时转换为503快速立即响应,如果您正确加载平衡器,它应该选择要服务的工作资源,并且比挂在那里时出现意外错误按摩更好。

  3. 例如:如果您正在使用节点服务器,您可以从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. 尝试批量分组呼叫,减少客户端和服务器的流量和总请求数。

    2. 尝试构建缓存中间层以处理不必要的重复请求。