我被要求用节点js创建一个简单的rest api,并创建一个脚本,通过api调用在数据库中创建10000个元素。我用Hapi框架创建了服务器。如果我向API发送单个或100个'PUT'请求,它会创建一个没有问题的新元素,但如果我尝试发出1000个或更多请求,它将无法创建所有这些或任何内容。我想知道可能是什么问题,如果我没有正确地编写脚本或服务器是问题。到目前为止,我收到了2个错误:
{ [Error: connect ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'connect' }
and (libuv) kqueue(): Too many open files in system
第一个尝试呼叫api 1000次,第二个尝试10000次
服务器的代码如下
var Hapi = require('hapi');
var server = new Hapi.Server();
var joi = require("joi");
var dbOpts = {
"url" : "mongodb://localhost:27017/songsDB",
"settings" : {
"db" : {
"native_parser" : false
}
}
};
server.register({
register: require('hapi-mongodb'),
options: dbOpts
},function (err) {
if (err) {
console.error(err);
throw err;
}
});
server.connection({
host: 'localhost',
port: 8080
});
server.route({
method: 'POST',
path: '/songs',
config: {
handler: function (request, reply) {
var newSong = {
name: request.payload.name,
album: request.payload.album,
artist: request.payload.artist
};
var db = request.server.plugins['hapi-mongodb'].db;
db.collection('songs').insert(newSong, {w:1}, function (err, doc){
if (err){
return reply(Hapi.error.internal('Internal MongoDB error', err));
}else{
reply(doc);
}
});
},
validate:{
payload: {
name: joi.string().required(),
album: joi.string().required(),
artist: joi.string().required()
}
}
}
});
server.start(function () {
console.log('Server running at:', server.info.uri);
});
请求的代码如下
var unirest = require('unirest');
for(var i = 1; i<=10000; i++){
unirest.post('http://localhost:8080/songs')
.header('Accept', 'application/json')
.send({ "name": "song"+i, "artist": "artist"+i, "album":"album"+i})
.end(function (response) {
console.log(response.body);
});
}
答案 0 :(得分:0)
如果在OSX下运行,请打开终端,然后尝试使用:
sudo launchctl limit maxfiles 1000000 1000000
然后再试一次。
答案 1 :(得分:0)
对于“系统中打开的文件太多”,看起来已达到系统限制。如果您使用的是Linux,则可以执行ulimit -a来显示所有设置。 有一个可能会限制您打开文件的数量。 打开文件(-n)1024
答案 2 :(得分:0)
假设您使用的是Mac或Linux,则需要增加系统允许的最大打开文件数。
如果将其插入终端,它将显示您的设置:
lsof | wc -l
您会看到自己打开的文件&#39;设置可能小于您尝试使用的数字。
要更改此设置,请使用以下命令:
ulimit -n #####
其中#####是一些任意数字(但高于你的数字)。
如果您使用的是Windows计算机,答案会稍微复杂一些。似乎Windows有一个每进程限制,可以修改(虽然听起来不容易)。在这里查看更多详细信息: Windows equivalent of ulimit -n
当我运行代码时,前11个POST会抛出错误。显然这是因为脚本在mongodb连接处于活动状态之前开始发送它们。我所做的只是在POSTing中加入了一个短暂的超时时间,让mongodb有机会开始呼吸。当我这样做时它工作得很好。完成后10000条记录。
我所改变的是:
setTimeout(function () {
for(var i = 1; i<=10000; i++){
unirest.post('http://localhost:8080/songs')
.header('Accept', 'application/json')
.send({ "name": "song"+i, "artist": "artist"+i, "album":"album"+i})
.end(function (response) {
//console.log(response.body);
});
}
}, 5000);