Nodejs 页面并发访问 如何防止阻塞
Nodejs 页面并发访问 如何防止阻塞
刚刚开始学习node,在看教程http://www.nodebeginner.org/index-zh-cn.html的过程中,遇到这个问题: function start(){ function onReq(req,res){ res.writeHead(200,{“Content-Type”:“text/plain”}); sleep(5000); res.write(“hello”); res.end(); } http.createServer(onReq).listen(9999); console.log(“server has started”); } function sleep(mileSecond){ var time=new Date().getTime(); while(new Date().getTime()<time+mileSecond){
} }
如果同时打开两个页面,访问http://localhost:9999/ 若使先启动的页面不会对第二个页面造成阻塞,代码应该怎么写? 大家帮忙指导一下,谢谢~
为了防止Node.js中的阻塞问题,并发访问页面时确保每个请求都能高效处理,我们可以使用异步编程的方法。在你的例子中,sleep
函数是一个同步操作,会导致事件循环被阻塞,直到 sleep
函数执行完毕。这将导致其他请求无法及时得到响应。
为了解决这个问题,我们可以使用异步函数或者利用Node.js的内置模块如 setTimeout
来实现非阻塞操作。以下是如何修改你的代码来避免阻塞:
const http = require('http');
function start() {
function onRequest(req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
// 使用 setTimeout 实现代理的非阻塞延时
setTimeout(() => {
res.write("hello");
res.end();
}, 5000); // 延时5秒
}
http.createServer(onRequest).listen(9999);
console.log("Server has started");
}
start();
解释
-
setTimeout
: 这个函数是非阻塞的,它允许你延迟执行一个函数或指定一段代码,而不会阻塞事件循环。当指定的时间到达后,该函数会被添加到事件队列中,等待事件循环的下一个周期来执行。 -
异步编程: Node.js 是基于事件驱动和非阻塞I/O模型构建的,这意味着它非常适合处理大量并发连接。通过使用非阻塞API(如
setTimeout
),可以确保服务器能够高效地处理多个并发请求,而不是因为一个长时间运行的任务而阻塞整个进程。
总结
通过将阻塞操作替换为异步操作,我们可以确保Node.js应用能够更好地处理并发请求,提供更流畅的用户体验。在实际开发中,尽量使用非阻塞方法和异步编程模式,以充分利用Node.js的优势。
你把sleep去掉,代码里都写明阻塞,还怎么不阻塞? 或者用cluster开两个进程,第一条进程还是阻塞的。
好,谢谢,现在思路清晰多了。我去看看cluster
在这个问题中,你的代码使用了 sleep
函数来模拟一个耗时操作。然而,这会导致 Node.js 的事件循环被阻塞,从而影响其他请求的处理。
为了避免这种情况,你可以使用异步函数或者第三方库(如 async
或 Promise
)来处理耗时的操作。以下是一个使用 Promise 和 setTimeout
来实现非阻塞的方式:
示例代码
const http = require('http');
function start() {
function onReq(req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
// 使用 Promise 和 setTimeout 来实现非阻塞的延迟
new Promise(resolve => setTimeout(resolve, 5000)).then(() => {
res.write("hello");
res.end();
});
}
http.createServer(onReq).listen(9999, () => {
console.log("server has started");
});
}
start();
解释
-
new Promise(resolve => setTimeout(resolve, 5000))
: 这里我们创建了一个新的 Promise,它会在 5 秒后通过resolve
函数解决。 -
.then(() => { ... })
: 当 Promise 被解决时,执行回调函数。在这个回调函数中,我们处理响应并发送给客户端。
这样,当多个请求同时到达时,每个请求都会被独立处理,而不会相互阻塞。
这种方法利用了 JavaScript 的异步特性,使得 Node.js 能够在等待耗时操作完成的同时继续处理其他请求。