Van*_*ula 4 windows google-chrome v8 processor node.js
首先,我有一种直觉,这是一个完全完整的问题,但无论如何请听我说完。我在想,如果 Node Js 是一个单线程应用程序,那么我们是否可以在同一台机器上的不同端口上运行它的多个实例。假设我有 8 个线程处理器,这是否意味着我可以运行 8 个节点实例而不会影响性能。如果我安装了足够的内存,然后我可以为这 8 个实例进行负载平衡
(此处为 V8 开发人员。)
是的,一般来说,在同一台机器上运行多个 Node 实例可以增加完成的工作总量。这类似于拥有多个 Chrome 选项卡,每个选项卡都可以执行一些单线程 JavaScript 工作。
也就是说,它很可能不像“8 线程处理器上的 8 个实例提供 8 倍的总吞吐量”那么简单,原因如下:
(1) 如果您实际上是指“8 个线程”,即 4 个内核 + 超线程,那么从 4 个进程到 8 个进程可能会带来 20-40% 的改进(取决于硬件架构和特定工作负载),而不是 2 倍。
(2) V8 确实使用多个线程用于内部目的(主要是编译和垃圾收集),这也是单个 Node 实例可能(取决于工作负载)使用多个 CPU 内核/线程的原因之一。
(3) 另一个原因是虽然 JavaScript 是单线程的,但 Node 不仅仅执行 JavaScript 的单线程。后台发生的各种事情(准备就绪时会触发 JS 回调)也需要 CPU 资源。
(4) 最后,CPU 不一定是你的瓶颈。如果您的服务器性能受到网络或磁盘等因素的限制,那么生成更多实例将无济于事;相反,它可能会使事情变得更糟。
长话短说:尝试并没有什么坏处。第一步,在一个实例上运行一个典型的工作负载,并查看当前的系统负载(CPU、内存、网络、磁盘)。如果他们都具有足够的闲置产能,尝试将两个实例,措施是否增加整体吞吐量,并检查系统的负荷试。然后继续添加实例,直到您注意到它不再有帮助。
除了@jmrk提供的出色答案之外,我还想对您问题的“不同端口”部分发表评论。
当涉及到多进程时,nodejs 最伟大的事情之一就是集群模块。您可以运行 1 个进程并对其进行多次分叉,并且可以使它们全部侦听同一端口。因此,例如,您不必使用 Nginx 来管理所有端口。
如果您想部署到可能具有不同核心数量的计算机集群,您可以通过将操作系统模块引入游戏来动态地完成此操作。
const cluster = require('cluster')
if (cluster.isMaster) {
// Creates the Forks
process.title = 'my-node-app-master'
const { length: numberOfProcs } = require('os').cpus()
for (let i = 0; i < numberOfProcs; i++) {
cluster.fork()
}
// and here you can fork again when one of the forks dies
cluster.on('exit', (worker, code, signal) => {
console.error(`worker ${worker.process.pid} died (${signal || code}). restarting it in a sec`)
setTimeout(() => cluster.fork(), 1000)
})
} else {
// run your server
const http = require('http')
process.title = 'my-node-app-fork'
http.Server((req, res) => {
res.writeHead(200)
res.end(`hello world from pid ${process.pid}\n`)
}).listen(8000)
}
Run Code Online (Sandbox Code Playgroud)
这process.title将有助于检查过程。我在我的机器上运行该代码我得到了:
$ ps aux | grep node-app
daniel 8062 1.1 0.1 550008 31380 pts/1 Sl+ 12:27 0:00 my-node-app-master
daniel 8069 0.5 0.1 549168 30476 pts/1 Sl+ 12:27 0:00 my-node-app-fork
daniel 8070 0.3 0.1 549176 30644 pts/1 Sl+ 12:27 0:00 my-node-app-fork
daniel 8077 0.5 0.1 549168 30376 pts/1 Sl+ 12:27 0:00 my-node-app-fork
...
daniel 8157 0.3 0.1 549168 30668 pts/1 Sl+ 12:27 0:00 my-node-app-fork
daniel 8194 0.0 0.0 9028 2468 pts/2 R+ 12:28 0:00 grep --color=auto node-app
Run Code Online (Sandbox Code Playgroud)
然后提出几个要求:
$ curl http://localhost:8000
hello world from pid 8069
$ curl http://localhost:8000
hello world from pid 8070
$ curl http://localhost:8000
hello world from pid 8077
Run Code Online (Sandbox Code Playgroud)
当你杀死一个子进程时
$ kill -9 8077
Run Code Online (Sandbox Code Playgroud)
日志将显示
worker 8077 died (SIGKILL). restarting it in a sec
Run Code Online (Sandbox Code Playgroud)
我知道它与您的主要问题没有直接关系,但它仍然相关,我认为人们可以充分利用这一点。