无法达到单个服务器的最大 tcp 连接数
Can't reach max tcp connections for single server
我正在 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
您没有绑定出站连接套接字。这会导致操作系统为它们分配一个本地源 IP 地址和端口。很可能它对所有这些都使用相同的本地源 IP 地址 (127.0.0.1),因此只有大约 65,000 个端口。将它自己绑定到环回范围内的本地 IP 地址和非特权范围内的端口的随机组合。如果您得到 EADDRNOTAVAIL
,请尝试不同的随机组合。
我正在 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
您没有绑定出站连接套接字。这会导致操作系统为它们分配一个本地源 IP 地址和端口。很可能它对所有这些都使用相同的本地源 IP 地址 (127.0.0.1),因此只有大约 65,000 个端口。将它自己绑定到环回范围内的本地 IP 地址和非特权范围内的端口的随机组合。如果您得到 EADDRNOTAVAIL
,请尝试不同的随机组合。