首页 文章

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

提问于
浏览
175

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

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

4 回答

  • 15

    最大连接数受客户端和服务器端的某些限制的影响,尽管有点不同 .

    On the client side: 增加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个出站连接 .

    To change the values

    sysctl net.ipv4.ip_local_port_range="15000 61000"
    sysctl net.ipv4.tcp_fin_timeout=30
    

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

    tcp_tw_recycletcp_tw_reuse 的典型Linux机器上的默认Sysctl值将是

    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 option is quite problematic for public-facing servers as it won’t handle connections from two different computers behind the same NAT device ,这是一个难以察觉并等待咬你的问题 . 请注意 net.ipv4.tcp_tw_recycle 来自Linux4.12 removed .

    On the Server Side: net.core.somaxconn 值具有重要作用 . 它限制了排队到侦听套接字的最大请求数 . 如果您确定您的服务器应用程序's capability, bump it up from default 128 to something like 128 to 1024. Now you can take advantage of this increase by modifying the listen backlog variable in your application'的监听呼叫,则为等于或大于等于整数 .

    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写入调用的次数 . 我自己的偏好是使用一个缓冲区,其中我将我希望发送的数据推送到客户端,然后在适当的点我将缓冲的数据写入实际的套接字 . 这种技术允许我使用大数据包,减少碎片,降低用户区域和内核级别的CPU利用率 .

  • 57

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

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

    • 检查TCP窗口设置是否足够大 . 除了真正快速的inet链路(数百mbps)或快速卫星链路之外,Linux默认设置适用于所有设备 . 你的带宽*延迟产品是多少?

    • 使用大数据包ping检查数据包丢失( ping -s 1472 ...)

    • 检查速率限制 . 在Linux上,这配置为 tc

    • 使用例如 iperf 确认您认为存在的带宽确实存在

    • 确认您的协议是正确的 . 记住延迟 .

    • 如果这是一个千兆局域网,你可以使用巨型数据包吗?是您?

    可能我误解了 . 也许你're doing something like Bittorrent, where you need lots of connections. If so, you need to figure out how many connections you'实际上正在使用(尝试 netstatlsof ) . 如果该数字很大,您可以:

    • 有很多带宽,例如100mbps . 在这种情况下,您实际上可能需要向上 ulimit -n . 不过,约有1000个连接(我的系统默认)很多 .

    • 网络问题导致连接速度变慢(例如数据包丢失)

    • 还有其他一些因素会让你失望,例如IO带宽,特别是如果你正在寻找 . 你检查过 iostat -x 吗?

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

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

  • 329

    为了改进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}'
    
  • 10

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

    From server side:

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

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

    例如:如果您正在使用节点服务器,您可以从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

    We can do some work in client side too:

    • 尝试批量分组呼叫,减少流量和总请求数量b / w客户端和服务器 .

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

相关问题