Nodejs 异步执行阻塞,strace发现堵在epoll_wait,求指点
Nodejs 异步执行阻塞,strace发现堵在epoll_wait,求指点
node新手,编译安装 ./configure --prefix=/path, 版本:v0.10.26
代码如下:
var http = require('http');
//http.globalAgent.maxSockets = 100;
for (var i = 0; i <= 500; i++)
{
http.get("http://www.baidu.com", function(res){
console.log('ok--\n');
}).on('error', function(e){
console.log(e);
});
}
执行效果:默认maxSockets是5,执行5个get后就会卡住。
strace 效果如下:
strace -p 25817 Process 25817 attached - interrupt to quit clock_gettime(CLOCK_MONOTONIC, {20601802, 628068955}) = 0 epoll_wait(5,
然后就阻塞在这里。 如果把maxSockets调大,执行指定数值后也会卡住。
请问是什么原因,是安装的不正确?
Node.js 异步执行阻塞,strace 发现堵在 epoll_wait,求指点
问题背景
你是一个 Node.js 新手,使用 Node.js v0.10.26 版本。你在尝试通过 http.get
方法并发请求百度网站时,遇到了异步执行阻塞的问题。通过 strace
工具发现程序阻塞在 epoll_wait
函数上。
示例代码
var http = require('http');
for (var i = 0; i <= 500; i++) {
http.get("http://www.baidu.com", function(res) {
console.log('ok--\n');
}).on('error', function(e) {
console.log(e);
});
}
问题分析
-
默认并发限制:Node.js 的 HTTP 客户端默认限制了同时进行的请求数量(默认为 5)。这是因为 Node.js 使用了一个全局的代理对象
http.globalAgent
来管理所有 HTTP 连接。 -
epoll_wait 阻塞:当你的请求超过了默认的最大并发数(5),后续的请求会被挂起,等待之前请求完成。此时,Node.js 的事件循环会进入阻塞状态,等待 I/O 操作完成,这可以通过
strace
看到它在epoll_wait
上阻塞。
解决方案
你可以通过调整 http.globalAgent.maxSockets
属性来增加并发连接的数量,从而避免阻塞问题。
var http = require('http');
// 设置最大并发连接数
http.globalAgent.maxSockets = 100;
for (var i = 0; i <= 500; i++) {
http.get("http://www.baidu.com", function(res) {
console.log('ok--\n');
}).on('error', function(e) {
console.log(e);
});
}
注意事项
- 性能与资源消耗:增加最大并发连接数可以解决当前问题,但需要注意可能会导致系统资源过度消耗,如文件描述符耗尽等。因此,在实际应用中需要根据实际情况合理设置。
- 版本更新:Node.js 的最新版本已经改进了这些默认行为,并且提供了更高效的 I/O 处理机制。建议升级到最新的 LTS 版本以获得更好的性能和稳定性。
通过上述方法,你应该能够解决在高并发情况下遇到的阻塞问题。
var http = require('http');
//http.globalAgent.maxSockets = 100;
for (var i = 0; i <= 500; i++) {
http.get("http://www.baidu.com", function(res) {
res.on('data', function(chunk) {
console.log('OK--\n');
});
}).on('error', function(e) {
console.log(e);
});
}
这样是ok的,http应该是开5个socket去做http请求而不是指的只发5个http请求
额 被你监视了 应该是 agent: null可以禁用agent
试了,ok。对其中的原理有点晕了。 为什么绑定on(‘data’, fun)就正常了呢?
这个问题的原因在于Node.js的HTTP客户端使用了全局代理http.globalAgent
来管理并发连接,默认情况下最大并发连接数为5。当超过这个数量时,后续请求会被挂起等待之前的连接释放。
你的代码中同时发起了500个HTTP请求,但因为默认的最大并发连接数只有5,所以当这5个请求完成后,其他请求才会继续进行。这也是为什么你会看到程序会卡在epoll_wait
上,因为它需要等待之前发起的连接完成。
你可以通过增加全局代理的最大连接数来解决这个问题:
http.globalAgent.maxSockets = 100; // 或者其他更大的值
示例代码如下:
var http = require('http');
http.globalAgent.maxSockets = 100; // 增加最大并发连接数
for (var i = 0; i <= 500; i++) {
http.get("http://www.baidu.com", function(res) {
console.log('ok--\n');
}).on('error', function(e) {
console.log(e);
});
}
这样做之后,即使你一次性发起大量的请求,Node.js也能够更好地管理这些连接,并且不会出现卡在epoll_wait
上的情况。