没有区别。因为当您调用 cluster.fork() 时,它会在 same entry file 上调用 child_process.fork 并保留子进程处理程序以进行进程间通信。
读取在cluster's master模块后面的行中定义的以下方法:167、102、51、52
让我们回到你的代码:
-
在示例 #1 中,它分配变量,为主进程和子进程创建应用实例,然后检查进程是否是主进程。
-
在示例 #2 中,它会检查进程是否为 master,如果没有,它会分配 var,创建应用实例并在端口上为子工作者绑定侦听器。
其实它会在 clild 进程中做同样的操作:
-
分配变量
-
创建应用实例
-
开始监听
我自己使用集群的最佳实践有 2 个步骤:
第 1 步 - 在单独的模块中使用自定义集群包装器并在应用程序调用中进行包装:
有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);
// no need for clustering if there is just 1 cpu
if (numCpu === 1 || !cluster.isMaster) {
return callable();
}
// saving 1 cpu for master process (1 M + N instances)
// or create 2 instances since 1 M + 1 Instance
// is ineffective when respawning instance
// better to have 1 M + 2 instances if cpu count 2
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 步 - 需要容器化时:
保持Step 1中的代码结构并使用docker
Cluster 模块将获取容器 orkestrator 提供的 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"]