首页 > 解决方案 > 无法达到单个服务器的最大 tcp 连接数

问题描述

我正在 CentOS7 中测试最大 tcp 连接。我将打开文件限制更改为 1000000(ulimit -n 1000000) 并编辑sysctl.conf如下所示。然后我用 node.js 测试如下代码(单服务器):

var net = require('net');
var count = 0
//server
let server = net.createServer(function(conn){
    conn.on("close", function(code, reason){
        console.log("close", code, reason);
    })
    conn.on("error", function(code, reason){
        console.log("error close", code, reason);
    })
}).listen({port : 8080, host: "0.0.0.0", backlog: 100000}).on("connection", _=>{count++});

//client
setInterval(_=>{new Array(300).fill(1).map((_,index)=>index+1926).map(p=>{
    new net.Socket().connect(8080,'127.0.0.1')
        .on('error',function(e){
            console.log(count);
            console.log(e);
            process.exit()}
        );
    })&&console.log('connection count:',count)},10)

结果:

connection count: 64200
connection count: 64500
64500
{ Error: connect EADDRNOTAVAIL 127.0.0.1:8080 - Local (127.0.0.1:0)
    at internalConnect (net.js:872:16)
    at defaultTriggerAsyncIdScope (internal/async_hooks.js:294:19)
    at defaultTriggerAsyncIdScope (net.js:962:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)
  errno: 'EADDRNOTAVAIL',
  code: 'EADDRNOTAVAIL',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 8080 }

它在连接数达到 64500 时抛出 EADDRNOTAVAIL。然后我尝试了多个服务器,如下所示:

var net = require('net');
var count = 0
//server
new Array(300).fill(1).map((_,index)=>index+1926).map(p=>{
    net.createServer().listen(p).on('connection',_=>count++)
    })

//client
setInterval(_=>{new Array(300).fill(1).map((_,index)=>index+1926).map(p=>{
    new net.Socket().connect(p,'127.0.0.1')
        .on('error',function(e){
            console.log(e);
            process.exit();
        })})&&console.log('connection count:',count);},10)

结果:

connection count: 392400
connection count: 392700
Aborted (core dumped)

为什么多服务器连接可以超过390000,而单服务器连接只能达到64500并抛出EADDRNOTAVAIL错误?


/etc/sysctl.conf

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 10

net.ipv4.tcp_keepalive_time = 1200

net.ipv4.tcp_max_tw_buckets = 5000

fs.file-max = 1000000

net.ipv4.ip_local_port_range= 1024 65535

net.core.somaxconn = 65535

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 65535

net.ipv4.tcp_synack_retries = 2

net.ipv4.tcp_syn_retries = 2

标签: node.jslinuxsocketstcpcentos7

解决方案


您没有绑定出站连接套接字。这会导致操作系统为它们分配本地源 IP 地址和端口。很可能它对所有这些都使用相同的本地源 IP 地址 (127.0.0.1),因此只有大约 65,000 个端口。将它自己绑定到环回范围内的本地 IP 地址和非特权范围内的端口的随机组合。如果你得到EADDRNOTAVAIL,请尝试不同的随机组合。


推荐阅读