Open closertb opened 5 years ago
你好,我也遇到了一样的问题,先上代码 node 14.18.2
const Koa = require('koa');
const cluster = require("cluster")
const PORT = 4000
const clusterWorkerSize = 2
if (clusterWorkerSize > 1) {
if (cluster.isMaster) {
console.log(`master ${process.pid}`)
for (let i=0; i < clusterWorkerSize; i++) {
cluster.fork()
}
cluster.on("exit", function(worker) {
console.log("Worker", worker.id, " has exitted.")
})
} else {
console.log(`worker ${process.pid}`)
createServer()
}
} else {
createServer()
}
function createServer(){
const app = new Koa();
app.use(async (ctx) => {
const url = ctx.request.url;
if (url === '/') {
ctx.body = {name: 'xxx', age: 14}
}
if(url==='/compute'){
const sum = compute()
ctx.body={sum}
}
})
app.listen(PORT, () => {
console.log(`listening on port ${PORT} with the single worker ${process.pid}`)
})
}
function compute(){
let sum=0
for (let i = 0; i <100000000000 ; i++) {
sum+=i
}
return sum
}
运行后,输出
master 19489
worker 19490
worker 19491
listening on port 4000 with the single worker 19490
listening on port 4000 with the single worker 19491
创建了一个master和两个worker,worker分别是两个http服务,
然后我请求/compute
和/
后者还是被阻塞了
难道我一定要把createServer代码写到另一个文件里,然后fork(这个文件)
吗?
尴尬,代码没问题,是测试方法有问题。
第二次请求阻塞,是因为cluster的调度策略。
当集群创建后,master会随机选一个进程作为优先进程来处理所有请求,所以compute
请求进来后,a进程阻塞了,/
请求进来master还是会分配给a进程,并不会直接分配给b进程,当再请求一次/
,master才会交给b进程来处理。
而且即使在compute
后,停顿20秒后请求还是会阻塞,也就是说cluster模块缺少了一种场景,根据worker的返回超时来判断这个进程已经不能使用了
最近一直在接触Node服务端相关的东西,前端的知识真的是像大海一样:我太水。
在掘金读到一篇关于深入理解Node.js 中的进程与线程, 里面讲到了线程阻塞,为了让自己印象深刻,我就复现了这个过程,然后用最近学会的pm2开启多线程解决这个顽疾时 -> 失败了,当发起计算请求时,再发起其他请求,就一直被阻塞,源码地址见下方。
});
最后
如果对上面有疑惑,可直接下载源码,运行调试,感受多进程。关于Node多进程,一张来自于阿里大佬们的图画的很清楚: 淘宝大佬们的三篇古董:关于Node: