【问题标题】:ENOBUFS when creating to many sockets with socket.io使用 socket.io 创建多个套接字时的 ENOBUFS
【发布时间】:2016-10-26 19:02:39
【问题描述】:

我想做的事:

我编写了一个使用持久 websocket 连接(无长轮询)的 node.js 客户端/服务器应用程序。我想对我的服务器进行压力测试,以调整它的性能并了解限制,以便我可以阻止由于过载而导致的新传入连接。不幸的是,我每次都卡在一个特定数量的套接字连接上,因此我认为这可能与操作系统或节点设置有关。

问题:

我有一个创建 10k 套接字连接的客户端,服务器可以完美地处理这个问题。当我用另外 10k 连接启动第二个客户端时,一旦服务器保持 14k 并发连接,我的客户端应用程序就会开始出现以下错误:

engine.io-client:socket 套接字关闭原因:“传输错误” +0ms engine.io-client:socket socket error {"type":"TransportError","description":{"code":"ENOBUFS","errno":"ENOBUFS","syscall":"connect","地址":"127.0.0.1","端口":5433,"类型":"错误","目标":{"域":​​null,"_events":{},"_eventsCount":4,"_socket" :null,"_ultron":null,"_closeReceived":false,"bytesReceived":0,"readyState":0,"supports":{"binary":true},"extensions":{},"_isServer": false,"url":"ws://127.0.0.1:5433/socket.io/?EIO=3&transport=websocket","protocolVersion":13,"binaryType":"buffer"}}} +0ms

我的 client1.js 和 client2.js 看起来像这样:

function createClient(){
    var socket = require('socket.io-client')('http://127.0.0.1:5433', {transports:['websocket']});

    socket.connect();

    // Send a bit data every 2.5s to simulate a bit traffic
    setInterval(function () {
        socket.emit("sessionCheck", "ok");
    }, 2500);
}

var clients=0;
var id =setInterval(function() {
    createClient();
    clients++;
    if(clients >= 10000)
        clearInterval(id);
}, 1);

我的 server.js 如下所示:

var http = require('http');
var httpServer = http.createServer(handler);
var io = require('socket.io')(httpServer, {pingTimeout: 60 * 1000, pingInterval: 5 * 1000});

io.on('connection', function (socket) {
    socket.on('sessionCheck',  function(data){onSessionCheck(socket,data)});
});

setInterval(function(){
    console.log(io.engine.clientsCount + " websockets are connected");
}, 5000);

httpServer.listen(5433, "0.0.0.0", 5000); // port, hostname, backlog

console.log("server running now...");

function onSessionCheck(){
    //console.log("Incoming check");
}

function handler (req, res) {
    fs.readFile(__dirname + '/index.html',
        function (err, data) {
            if (err) {
                res.writeHead(500);
                return res.end('Error loading index.html');
            }

            res.writeHead(200);
            res.end(data);
        })
};

【问题讨论】:

    标签: javascript node.js windows sockets socket.io


    【解决方案1】:

    正如我已经假设的那样,解决方案是 windows (MaxUserPort) 中的一个选项,您可以在 regedit 中更改它。查看 MSDN 描述以了解更多信息:https://support.microsoft.com/en-us/kb/196271。您可以将其设置为最大值 65534。

    【讨论】:

      【解决方案2】:

      您在 Slack 中说您已经知道 –max-old-space-size,并且您尝试过它并没有帮助。现在我可以确认使用此选项(我尝试了值 2048-65000)可以防止我从一台服务器获得超过 ~18-20k 的并发连接到一台服务器。删除该选项给我〜29500个并发连接。我使用 20 美元的 DigitalOcean vps(2 GB,2 核),而 29500 占用了我服务器的所有可用内存 - 这就是为什么我现在无法拥有更多连接。

      更新

      Linux? 尝试在服务器上检查调整以下值:

      • net.nf_conntrack_max(我用65536
      • net.netfilter.nf_conntrack_max(我用65536
      • cat /proc/sys/fs/nr_open 给我1048576
      • cat /proc/sys/fs/file-nr 给我5056 0 2097152
      • cat /proc/sys/fs/file-max 给我2097152
      • net.ipv4.ip_local_port_range(我用2000 65535
      • net.core.somaxconn(我用65000
      • ulimit -n 给我1048576

      这可能会让您大致了解如何设置参数https://easyengine.io/tutorials/linux/sysctl-conf/

      也许您应该检查您的客户端服务器的一些值(例如ip_local_port_rangefile-nrulimit -n

      您可能还想查看日志(/var/log/messages/var/log/syslogdmesg)。

      我终于得到了 34469 个连接,然后 oom-killer 在我的客户端机器上杀死了节点

      【讨论】:

      • 我使用的是 Windows,但我仍然在一个强大的 Windows 服务器上达到了相对较低的最大连接数(13.5k),它有足够的 ram 和 cpu 空闲。我尝试删除 max-old-space-size 参数而没有任何效果。在某些时候,服务器会失去连接(很可能是因为客户端/服务器在给定的超时时间内不再响应 ping/pong)。
      猜你喜欢
      • 2018-01-19
      • 1970-01-01
      • 2019-06-06
      • 2018-12-11
      • 2012-07-23
      • 1970-01-01
      • 2023-03-28
      • 2020-08-18
      • 2013-12-28
      相关资源
      最近更新 更多