如何正确关闭node.js服务器上的MongoClient连接?

时间:2014-11-27 03:28:52

标签: node.js mongodb httpserver

我试图编写一个简单的基准来测试mongodb插入和查询。它在浏览器中运行良好,但是当我尝试使用apache基准测试加载它时,DB似乎在一定量(大约100-150)之后崩溃连接,即使MongoDB服务器本身保持运行。 以下是基准输出:

ab -n 10000 -c 100 http://127.0.0.1:8888/?action=insert

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
apr_socket_recv: Connection refused (61)
Total of 100 requests completed

MongoDB最多可达100-150个连接:

2014-11-26T22:21:15.596-0500 [conn116] end connection 127.0.0.1:54583 (136 connections now open)
2014-11-26T22:21:15.598-0500 [conn130] end connection 127.0.0.1:54597 (125 connections now open)
2014-11-26T22:22:05.844-0500 [clientcursormon] mem (MB) res:44 virt:3128
2014-11-26T22:22:05.844-0500 [clientcursormon]  mapped (incl journal view):640
2014-11-26T22:22:05.844-0500 [clientcursormon]  connections:0

但介于两者之间的node.js服务器崩溃了:

/Users/rw3iss/Sites/benchmark/node_tests/node_modules/mongodb/lib/mongodb/mongo_client.js:409
          throw err
                ^
TypeError: Cannot call method 'collection' of null
    at /Users/rw3iss/Sites/benchmark/node_tests/index.js:37:23
    at /Users/rw3iss/Sites/benchmark/node_tests/node_modules/mongodb/lib/mongodb/mongo_client.js:406:11
    at process._tickCallback (node.js:419:13)

我的index.js文件正在执行此操作:

var mongo = require('mongodb').MongoClient;

function test_insert(response) {
    mongo.connect("mongodb://localhost:27017/benchmark", function(err, db) {
        var data = { name: 'name', value: 'blah' };
        var collection = db.collection('benchmark');  //**this is line 37**
        collection.insert(data, function(err, docs) {
            response.end("Item inserted.");
        });

        db.close();
    });
}

主要的失败点是数据库打开操作。 node.js服务器吐出:

throw new Error("db object already connecting, open cannot be called multiple times

任何人都可以帮我找出原因吗?在DB操作后我没有正确关闭连接吗?

更新:请参阅答案。 但是,查询似乎很慢:

ab -n 100 -c 10 http://127.0.0.1:8888/?action=query
Requests per second:    2.32 [#/sec] (mean)

我的查询代码是:

function test_query(name, response) {
    var result = [];

    if (client) {
        if (!collection) {
          collection = new mongodb.Collection(client, 'benchmark');
        }

        function resultCallback(err, results) {
            if(name != null && results.length > 0)
                response.end(JSON.stringify(results[0]));
            else
                response.end(JSON.stringify(results));
        }

        var data = {};

        if(name != null) {
            data['name'] = name;
            collection.find(data).limit(1).toArray(resultCallback);
        } else {
            collection.find(data).toArray(resultCallback);
        }

    } else {
        // can perform reconnecting and then get collection and call callback
        console.log("Error, can't get connection");
    }
}

为什么表现得这么慢?我正如下面第一个答案中所述设置连接。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

正如JohnnyHK所述,我无法打开与每个查询的连接。这与PHP范例略有不同(我是node.js的新手)。我通过这种方式执行连接找到了解决方案:

var mongodb = require('mongodb');

var server = new mongodb.Server('localhost', 27017, { auto_reconnect: true });

var client;
var collection;

var benchmarkDb = new mongodb.Db('benchmark', server).open(function (err, c) {
  if (!err) {
    client = c;
    client.on('close', function() {
      client = null; // clear client
      collection = null; // clear old collections
      // connection closed
    });
  } else {
    // error connecting
    console.log("Error connecting to MongoDB", err);
  }
});


function test_insert(response) {
    if (client) {
        if (!collection) {
          collection = new mongodb.Collection(client, 'benchmark');
        }

        var data = { name: 'name', value: 'blah' };

        collection.insert(data, function(err, docs) {
            response.end("Item inserted.");
        });
    } else {
        console.log("Error, can't get connection");
    }
}