没有区别。因为当您调用cluster.fork()
时,它会在同一入口文件上调用child_process.fork
并保留子进程处理程序以进行进程间通信。
请阅读以下方法,在集群主节点模块的下方行中定义:167、102、51、52
让我们回到您的代码:
在示例#1中,它分配变量,为主进程和子进程创建应用程序实例,然后检查进程是否为主进程。
在示例#2中,它检查进程是否为主进程,如果不是,则为子工作进程分配变量,创建应用程序实例并绑定端口上的侦听器。
实际上,它会在子进程中执行相同的操作:
分配变量
创建应用程序实例
启动监听器
我使用集群的最佳实践有两个步骤:
第一步 - 在单独的模块中具有自定义集群包装器并将其包装在应用程序调用中:
拥有cluster.js
文件:
'use strict';
module.exports = (callable) => {
const
cluster = require('cluster'),
numCpu = require('os').cpus().length;
const handleDeath = (deadWorker) {
console.log('worker ' + deadWorker.process.pid + ' dead');
const worker = cluster.fork();
console.log('re-spawning worker ' + worker.process.pid);
}
process.on('uncaughtException',
(err) => {
console.error('uncaughtException:', err.message);
console.error(err.stack);
});
cluster.on('exit', handleDeath);
if (numCpu === 1 || !cluster.isMaster) {
return callable();
}
const instances = numCpu > 2 ? numCpu - 1 : numCpu;
console.log('Starting', instances, 'instances');
for (let i = 0; i < instances; i++, cluster.fork());
};
保持像下面这样简单的
app.js
,以实现模块化和可测试性(阅读关于
supertest
的内容):
'use strict';
const express = require("express");
const app = express();
app.get("/path", somehandler);
module.exports = app;
将应用程序在某个端口上提供服务必须由不同的模块处理,因此需要让 server.js
看起来像这样:
'use strict';
const start = require('./cluster');
start(() => {
const http = require('http');
const app = require('./app');
const listenHost = process.env.HOST || '127.0.0.1';
const listenPort = process.env.PORT || 8080;
const httpServer = http.createServer(app);
httpServer.listen(listenPort, listenHost,
() => console.log('App listening at http://'+listenHost+':'+listenPort));
});
在scripts
部分,您可以添加以下行到package.json
文件中:
"scripts": {
"start": "node server.js",
"watch": "nodemon server.js",
...
}
使用以下命令运行应用程序:
node server.js
, nodemon server.js
或者
npm start
, npm run watch
步骤2 - 当需要容器化时:
保持代码结构与步骤1相同,并使用docker
集群模块将获得由容器或编排工具提供的CPU资源
并且作为额外的功能,您可以使用docker swarm
、kubernetes
、dc/os
等按需扩展docker实例。
Dockerfile
:
FROM node:alpine
ENV PORT=8080
EXPOSE $PORT
ADD ./ /app
WORKDIR /app
RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh
RUN npm i
CMD ["npm", "start"]
child_process.fork
。如果我在fork之后实例化应用程序和其他变量,会消耗更多的内存吗?当您调用cluster.fork
时,它会调用child_process.fork
并再次运行同一文件。根据您的变量实例化方式,它可能被子进程或主进程消耗。因此,示例#2更值得推荐。 - num8er