我可以在工作线程中使用节点 http 服务器吗
Can I use node http server in worker threads
我知道集群模块,但对 worker_threads 有疑问。
代码示例
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}`)
})
}
当我在 Windows 上 运行 这段代码时,我得到了明显的错误
Error: listen EADDRINUSE: address already in use :::8080
但是它在 WSL 上运行没有错误
$ node ./index.js
Thread 2 is listening 8080
Thread 1 is listening 8080
但是在浏览器中,我总是只从单个工作人员那里得到响应,这取决于他们启动的顺序
我能否在工作线程中监听单个 http 端口?如果是,如何在此端口上进行负载平衡?为什么 nodejs 允许在 WSL 上监听相同的端口?
不,您不能在工作线程中侦听同一端口。在 Linux (Debian 10) 上,您的代码也会失败并出现预期的错误 Error: listen EADDRINUSE: address already in use :::8080
。预计它会在生产环境中失败。
这样做的原因是,尽管 Linux 确实支持通过 SO_REUSEPORT 共享端口,但这是一个相当新的功能并且 libuv
没有实现标志(不适用于 tcp
,至少)。我不知道为什么 WSL 没有为您产生错误,但如您所见,它不进行负载平衡。
以下是实现负载平衡的方法:改用 cluster
模块,因为它就是为此而设计的。或者,侦听不同的端口并使用单独的负载平衡器 - 但是,如果处理是完全独立的,那么最好生成单独的独立进程,而不是使用 worker_threads
模块。
我知道集群模块,但对 worker_threads 有疑问。
代码示例
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}`)
})
}
当我在 Windows 上 运行 这段代码时,我得到了明显的错误
Error: listen EADDRINUSE: address already in use :::8080
但是它在 WSL 上运行没有错误
$ node ./index.js
Thread 2 is listening 8080
Thread 1 is listening 8080
但是在浏览器中,我总是只从单个工作人员那里得到响应,这取决于他们启动的顺序
我能否在工作线程中监听单个 http 端口?如果是,如何在此端口上进行负载平衡?为什么 nodejs 允许在 WSL 上监听相同的端口?
不,您不能在工作线程中侦听同一端口。在 Linux (Debian 10) 上,您的代码也会失败并出现预期的错误 Error: listen EADDRINUSE: address already in use :::8080
。预计它会在生产环境中失败。
这样做的原因是,尽管 Linux 确实支持通过 SO_REUSEPORT 共享端口,但这是一个相当新的功能并且 libuv
没有实现标志(不适用于 tcp
,至少)。我不知道为什么 WSL 没有为您产生错误,但如您所见,它不进行负载平衡。
以下是实现负载平衡的方法:改用 cluster
模块,因为它就是为此而设计的。或者,侦听不同的端口并使用单独的负载平衡器 - 但是,如果处理是完全独立的,那么最好生成单独的独立进程,而不是使用 worker_threads
模块。