I know about cluster module, but question about worker_threads.
Code example
const { Worker, isMainThread, threadId } = require('worker_threads')
const { createServer } = require('http')
if (isMainThread) {
let w1 = new Worker(__filename)
let w2 = new Worker(__filename)
} else {
const server = createServer((req, res) => {
res.end(`response from thread ${threadId}`)
})
server.listen(8080, () => {
console.log(`Thread ${threadId} is listening ${server.address().port}`)
})
}
When I run this code on Windows, I get obvious error
Error: listen EADDRINUSE: address already in use :::8080
But it works without errors on WSL
$ node ./index.js
Thread 2 is listening 8080
Thread 1 is listening 8080
But in browser I always get response only from single worker, depends on order they started
Can I listen single http port in worker threads or not? If yes, how can I make load balancing on this port? Why nodejs allows to listen same port on WSL?
No, you cannot listen on the same port in worker threads. On Linux (Debian 10), your code fails with the expected error Error: listen EADDRINUSE: address already in use :::8080
as well. Expect it to fail in production environments.
The reason for this is that, even though Linux does support port sharing via SO_REUSEPORT, it's a fairly new feature and libuv
does not implement the flag (not for tcp
, at least). I have no idea why WSL is not producing an error for you, but as you can see, it does not do load balancing.
Here's how you can implement load balancing: use the cluster
module instead, since that's what it is designed for. Or, listen on different ports and use a separate load balancer - though, if the processing is totally independent, you may be better off spawning separate, independent processes, instead of using the worker_threads
module.