Node.js cluster模块fork实例未按预期工作,求代码修改方案
问题分析与修改方案
你的代码里,访问慢页面时首页也卡住的核心原因有两个:
- 慢页面的处理用了同步阻塞的大循环,会直接占用当前worker的事件循环,导致这个worker无法处理其他请求;
- 手动只创建了2个worker,若测试时首页请求恰好被分发到了正在处理慢请求的worker,就会出现卡顿。
修改步骤:
- 替换同步阻塞逻辑为异步操作
把耗时的同步循环换成异步任务,这样不会阻塞事件循环,worker能同时处理多个请求。比如用setTimeout模拟异步耗时操作:
else if (req.url === "/slow-page"){ // 用异步操作替代同步循环,避免阻塞事件循环 setTimeout(() => { res.writeHead(200, {"content-type": "text/plain"}); res.end("Slow Page"); }, 3000); // 模拟3秒耗时操作 }
- 根据CPU核心数自动创建worker
不要手动写cluster.fork()两次,而是根据CPU数量动态创建,最大化利用多核资源:
if(cluster.isMaster){ console.log(`Master process ${process.pid} is running`); // 遍历CPU核心数,创建对应数量的worker for(let i = 0; i < OS.cpus().length; i++){ cluster.fork(); } // 可选:worker退出时自动重启,提升服务稳定性 cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} exited, restarting...`); cluster.fork(); }); }else{ // worker逻辑不变(除了慢页面的异步修改) }
- 验证效果
修改后,当访问慢页面时,对应的worker会在异步任务等待时处理其他请求(比如首页),首页会快速加载;同时多worker的配置也能避免单个worker阻塞影响所有请求。
修改后的完整代码:
const cluster = require("node:cluster"); const http = require("node:http"); const OS = require("node:os"); console.log(`CPU核心数:${OS.cpus().length}`); if(cluster.isMaster){ console.log(`Master process ${process.pid} is running`); // 根据CPU核心数创建worker for(let i = 0; i < OS.cpus().length; i++){ cluster.fork(); } // worker退出自动重启 cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} exited, restarting...`); cluster.fork(); }); }else{ console.log(`Worker ${process.pid} started`); const server = http.createServer((req, res)=>{ if(req.url === "/"){ res.writeHead(200, {"content-type": "text/plain"}); res.end("Home Page"); } else if (req.url === "/slow-page"){ // 异步耗时操作,不阻塞事件循环 setTimeout(() => { res.writeHead(200, {"content-type": "text/plain"}); res.end("Slow Page"); }, 3000); } }); server.listen(8000, ()=> console.log(`Worker ${process.pid} listening on port 8000`)); }
内容的提问来源于stack exchange,提问作者Ashish Patel
相关产品推荐
相关产品推荐

