node.js - 无法达到单个服务器的最大 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
解决方案
您没有绑定出站连接套接字。这会导致操作系统为它们分配本地源 IP 地址和端口。很可能它对所有这些都使用相同的本地源 IP 地址 (127.0.0.1),因此只有大约 65,000 个端口。将它自己绑定到环回范围内的本地 IP 地址和非特权范围内的端口的随机组合。如果你得到EADDRNOTAVAIL
,请尝试不同的随机组合。
推荐阅读
- firebase - Firebase 事件发生时更新反应原生(博览会)UI
- python - 如何仅打印此输出的最后一行?
- r - 使用 read_html 在 R 中读取时处理 404 和其他错误 URL
- excel - 在 Excel VBA 中删除条件
- python - 在 sqlalchemy 中插入父对象时插入子对象列表
- javascript - Discord Bot 不会通过 node 上线。或节点 main.js
- google-apps-script - 如何使用应用程序脚本获取范围内所有单元格的背景颜色并将背景设置为相同大小的不同范围?
- shell - 删除 shell 脚本中的最后一个参数 (POSIX)
- c - 这个带有指向带有指针的结构的指针的c代码有什么问题?
- javascript - 如何使用 jquery 或普通 JS 从 div 中删除子元素