nxtedition/node-http2-proxy

Cluster support (Bug??)

hanspeter1 opened this issue · 17 comments

I just come across a strange bug here:
I wanted to test the speed of the proxys and use the cluster module. Very often I get this error:

connect EADDRINUSE 192.168.1.4:8090
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
  errno: 'EADDRINUSE',
  code: 'EADDRINUSE',
  syscall: 'connect',
  address: '192.168.1.4',
  port: 8090,
  statusCode: 503,
  connectedSocket: false,
  reusedSocket: false
}

But if I only use one worker, I get no error ???
Is http.request compatible with cluster?

ronag commented

Not sure if this is related to this library. Can you please provide a full example

Proxy

const Http = require("http");
const HttpProxy2 = require("http2-proxy");
const Cluster = require("cluster");


if (Cluster.isMaster) {
    // Create worker
    for (let core = 0; core < 8; core++) {
        Cluster.fork();
    }
} else {
    let httpServer = Http.createServer();
    httpServer.on("request", (req, res) => {
        HttpProxy2.web(req, res, {
            hostname: "localhost",
            port: 8090
        }, (err, req, res) => {
            if (err) {
                console.error(err)
            }
            res.end();
        });
    });

    httpServer.listen(8080)
}

Proxy-Target

const http = require('http')
const port = 8090

const requestHandler = (request, response) => {
  response.end('Hello Node.js Server!')
}

const server = http.createServer(requestHandler)

server.listen(port, (err) => {
  if (err) {
    return console.log('something bad happened', err)
  }

  console.log(`server is listening on ${port}`)
})

Log

Error: connect EADDRINUSE 192.168.1.4:8090
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
  errno: 'EADDRINUSE',
  code: 'EADDRINUSE',
  syscall: 'connect',
  address: '192.168.1.4',
  port: 8090,
  statusCode: 503,
  connectedSocket: false,
  reusedSocket: false
}
ronag commented

I just tried your example and it works fine.

The error does not appear for the first ~300 requests.
I used bombardier (https://github.com/codesenberg/bombardier) with bombardier -c 125 -n 10000000 http://localhost:8080 to generate requests.

System: Win10 / Node 12.18.1

ronag commented

Seems like a common problem, request/request#210

ronag commented

Do you have the same problem with Node 14?

What version of node?

Node.js 12.18.1

Do you have the same problem with Node 14?

I will test

Do you have the same problem with Node 14?

Same result ... :(

Error: connect EADDRINUSE 127.0.0.1:8090
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16) {
  errno: -4091,
  code: 'EADDRINUSE',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 8090,
  statusCode: 503,
  connectedSocket: false,
  reusedSocket: false
}
ronag commented

I don't have bombardier nor does it seem to be on brew. Is there any other tool I can use to try and reproduce on Mac?

ronag commented

Can you try with:

 HttpProxy2.web(req, res, {
            hostname: "localhost",
            port: 8090,
            onReq: options => http.request({ ...options, agent: false })
        }, (err, req, res) => {
            if (err) {
                console.error(err)
            }
            res.end();
        });

and also:

const agent = new http.Agent({ maxSockets: 128 });

...

 HttpProxy2.web(req, res, {
            hostname: "localhost",
            port: 8090,
            onReq: options => http.request({ ...options, agent })
        }, (err, req, res) => {
            if (err) {
                console.error(err)
            }
            res.end();
        });
ronag commented

I think you are probably hitting the maximum number of concurrent sockets on your platform.

Can you try with:

 HttpProxy2.web(req, res, {
            hostname: "localhost",
            port: 8090,
            onReq: options => http.request({ ...options, agent: false })
        }, (err, req, res) => {
            if (err) {
                console.error(err)
            }
            res.end();
        });

and also:

const agent = new http.Agent({ maxSockets: 128 });

...

 HttpProxy2.web(req, res, {
            hostname: "localhost",
            port: 8090,
            onReq: options => http.request({ ...options, agent })
        }, (err, req, res) => {
            if (err) {
                console.error(err)
            }
            res.end();
        });

Same error. Maybe it's a Windows bug

ronag commented

I would try and open an issue on the nodejs issue tracker. Maybe you can get help there. I'm unsure how to help here. I don't have a Windows workstation unfortunately to continue digging.

Now I know what the error was ... Windows!
Do not get an error on Ubuntu 20.04.
Next I'll try that (https://docs.oracle.com/cd/E26180_01/Search.94/ATGSearchAdmin/html/s1207adjustingtcpsettingsforheavyload01.html).

ronag commented

Cool. I'm closing this issue.

THX