【问题标题】:handle multiple request to node js api处理对节点 js api 的多个请求
【发布时间】:2015-04-14 00:18:36
【问题描述】:

我被要求用node 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);
});
}

【问题讨论】:

  • 你在什么操作系统上运行这个?

标签: javascript node.js mongodb rest testing


【解决方案1】:

如果在 OSX 下运行,打开终端然后尝试使用:

sudo launchctl limit maxfiles 1000000 1000000

然后再试一次。

【讨论】:

    【解决方案2】:

    对于“系统中打开的文件过多”,您似乎达到了系统的限制。如果您使用的是 Linux,则可以执行 ulimit -a 来显示所有设置。 有一个可能会限制您打开文件的数量。 打开文件 (-n) 1024

    【讨论】:

      【解决方案3】:

      假设您使用的是 Mac 或 Linux,您需要增加系统允许的最大打开文件数。

      如果您将其插入终端,它将显示您的设置:

      lsof | wc -l
      

      您会看到您的“打开文件”设置可能小于您尝试使用的数字。

      要更改此设置,请使用以下命令:

      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);
      

      【讨论】:

      • 感谢您提供的信息,现在打开文件问题已经解决了。虽然当我尝试发出 10000 个请求时,其中许多请求无法处理,并且没有元素添加到数据库中。你知道这可能是什么问题吗?
      • 只是好奇,但是您使用节点向自身发送 Ajax 调用是否有原因?
      • 我开始学习node,所以我发现用node来做服务器和请求脚本都很方便。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多