uNetworking / uWebSockets.js

μWebSockets for Node.js back-ends :metal:
Apache License 2.0
7.85k stars 570 forks source link

Dropping connections beyond 5.8K #457

Closed be-thomas closed 3 years ago

be-thomas commented 3 years ago

Node ws library is able to handle 20K concurrent connections easily. However, uws is struggling beyond was. And I thought this was faster. Please inform me if I'm missed something in my code.

My observation while stress testing is that, just after 5.8K opened connections, the uWS server starts dropping many connections(around 700 of them) and goes down to 5.1K connections. After that it keeps connecting more until it reaches that 5.8K connections where again it drops around 700 connections and goes down to 5.1K. So it has some kind of rotational mechanism. But I'm not sure what this is for.

Screenshot_2021-02-17_15-35-28

This can be reproduced.

Node uWS server code -

const { SHARED_COMPRESSOR } = require('uWebSockets.js');

var users = 0;

require('uWebSockets.js').App().ws('/*', {
    idleTimeout: 30,
    maxBackpressure: 1024,
    maxPayloadLength: 512,
    compression: SHARED_COMPRESSOR,

    open: ws => {
        users += 1;
        ws.id = users;
        console.log("opened #" + ws.id);
    },
    close: ws => {
        users -= 1
        console.log("closed #" + ws.id)
    },

    message: (ws, message, isBinary) => {
        // 
    }
}).get('/*', (res, req) => {

  /* It does Http as well */
  res.writeStatus('200 OK').writeHeader('IsExample', 'Yes').end('Hello there!');

}).listen(9001, (listenSocket) => {

  if (listenSocket) {
    console.log('Listening to port 9001');
  }

});

Node WS client code -

const WebSocket = require('ws');

const host = "127.0.0.1";
const port = 9001;
const count = 20000;
var i=0;

let interval = setInterval(() => {
    if(i == count) {
        clearInterval(interval);
        return;
    }
    const ws = new WebSocket('ws://' + host + ":" + port);
    console.log("Connecting #" + (i+1));
    ws.id = i+1
    ws.start = (new Date()).getTime();

    ws.on('open', function open() {
        ws.end = (new Date()).getTime();
        var diff = ws.end - ws.start
        console.log("Time taken for #" + ws.id + " - " + diff + " ms");
    });

    ws.on('message', function incoming(data) {
        console.log(data);
    });
    ws.on('error', () => {
        console.log("Hung Up - #" + ws.id);
        i--;
    });
    ws.on('close', () => {
        console.log("Closed #" + ws.id);
        i--;
    })
    i++;
}, 5);

I want to know how to increase this 5.8K limit.

ghost commented 3 years ago

uWS has built-in heartbeat and timeout management. That's what idleTimeout is. If you set it to 0 it won't close connections and you'll have an equal case.

https://alexhultman.medium.com/millions-of-active-websockets-with-node-js-7dc575746a01