在 NodeJs 中,为什么我最后一个分叉的工作进程每次都处理请求,尽管 7 个工作进程仍然是理想的?
In NodeJs, Why my last forked worker process handle request every time, Although 7 worker process remain ideal?
我想使用集群模块 运行 使用工作进程并排表示服务器。这是我的完整脚本。
const express = require('express');
const cluster = require('cluster');
const os = require('os');
const totalCPUs = os.cpus().length;
const PORT = 3000;
if (cluster.isMaster) {
console.log(`Number of logical cpus is available: ${totalCPUs}`);
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < totalCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
console.log("Let's fork another worker!");
cluster.fork();
});
} else {
const app = express();
console.log(`Worker ${process.pid} started`);
app.get('/', (req, res) => {
res.send(`Performance example: ${process.pid} `);
});
function spin(duration) {
const startTime = Date.now();
while (Date.now() - startTime < duration) {
// block the event loop
}
}
app.get('/delay', (req, res) => {
// after some delay
spin(9000);
res.send(`Ding ding ding! ${process.pid}`);
});
app.listen(PORT, () => {
console.log(`Worker process ${process.pid} Listening on ${PORT}`);
});
}
每当我在浏览器中打开多个选项卡并点击相同的 http://localhost:3000/delay
api 然后所有请求 运行 仅由最后创建的子进程串联。我将如何使用保留所有子进程?
如果您从浏览器发出多个完全相同的请求,那么浏览器本身可能会保留您的第二个请求,直到第一个请求 returns(可能希望使用缓存的结果)。如果你想打败这个浏览器“功能”,你可以为每个 URL 添加一个唯一的查询参数,如下所示:
const mainUrl = "http://localhost:3000/delay";
const uniqueUrl = mainURL + "?r=" + Math.random();
然后,将您的请求从浏览器发送到uniqueUrl
。这将防止浏览器序列化它们以希望使用以前缓存的结果。为您从浏览器发送的每个请求生成一个新的 uniqueUrl
。
你的服务器会忽略查询参数,但是浏览器会认为每个 URL 是不同的,因此不会让第二个等待第一个响应等等,让你得到一些请求并行到同一条路线。请记住,浏览器仍然有关于它将向同一主机发出多少同时请求的规则,因此您仍然不一定会并行获得所有请求,但您应该获得一些。
或者,使用单独的实际客户端发送每个请求,这样单个浏览器客户端就不会阻止您。
或者,从客户端(如 nodejs 客户端测试应用程序)发送多个请求,该客户端不执行浏览器执行的“保留缓存”。
我想使用集群模块 运行 使用工作进程并排表示服务器。这是我的完整脚本。
const express = require('express');
const cluster = require('cluster');
const os = require('os');
const totalCPUs = os.cpus().length;
const PORT = 3000;
if (cluster.isMaster) {
console.log(`Number of logical cpus is available: ${totalCPUs}`);
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < totalCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
console.log("Let's fork another worker!");
cluster.fork();
});
} else {
const app = express();
console.log(`Worker ${process.pid} started`);
app.get('/', (req, res) => {
res.send(`Performance example: ${process.pid} `);
});
function spin(duration) {
const startTime = Date.now();
while (Date.now() - startTime < duration) {
// block the event loop
}
}
app.get('/delay', (req, res) => {
// after some delay
spin(9000);
res.send(`Ding ding ding! ${process.pid}`);
});
app.listen(PORT, () => {
console.log(`Worker process ${process.pid} Listening on ${PORT}`);
});
}
每当我在浏览器中打开多个选项卡并点击相同的 http://localhost:3000/delay
api 然后所有请求 运行 仅由最后创建的子进程串联。我将如何使用保留所有子进程?
如果您从浏览器发出多个完全相同的请求,那么浏览器本身可能会保留您的第二个请求,直到第一个请求 returns(可能希望使用缓存的结果)。如果你想打败这个浏览器“功能”,你可以为每个 URL 添加一个唯一的查询参数,如下所示:
const mainUrl = "http://localhost:3000/delay";
const uniqueUrl = mainURL + "?r=" + Math.random();
然后,将您的请求从浏览器发送到uniqueUrl
。这将防止浏览器序列化它们以希望使用以前缓存的结果。为您从浏览器发送的每个请求生成一个新的 uniqueUrl
。
你的服务器会忽略查询参数,但是浏览器会认为每个 URL 是不同的,因此不会让第二个等待第一个响应等等,让你得到一些请求并行到同一条路线。请记住,浏览器仍然有关于它将向同一主机发出多少同时请求的规则,因此您仍然不一定会并行获得所有请求,但您应该获得一些。
或者,使用单独的实际客户端发送每个请求,这样单个浏览器客户端就不会阻止您。
或者,从客户端(如 nodejs 客户端测试应用程序)发送多个请求,该客户端不执行浏览器执行的“保留缓存”。