MongoDB Node.js原生驱动程序是否关闭连接?

8

在Node.js中,每个请求都打开MongoDB连接并在回调函数中关闭它是一个好的实践吗?

app.get('/some_route', function(){
      MongoClient.connect(url,function(err, db){
          //some db query with callback
          db.collection("some_collection").findOne(doc, function(err,item){
               if(err){
                      res.send(err);
                      //close db connection 
                      db.close();
                }else{
                      //do something with item
                      res.send(item);
                      //close db connection 
                      db.close();
                }

      });
    });

有人说每个请求都打开/关闭mongodb连接是不必要的,因为一旦打开,就可以共享一组连接池。
问题是如何维护和共享这个池?mongoose是否已经自动完成了这个操作?
特别是在mongodb超时或断开连接的情况下,需要重新连接吗?
我在这里找到了矛盾的答案 close mongodb connection per request or not 我阅读的几乎所有在线文档 nodejs mongodb native driver 和示例代码中,都在回调函数中将db.open()与db.close()配对使用。
根据christkv的答案,可能会编写以下代码:
var p_db=null;
var c_opt = {server:{auto_reconnect:true}};

app.get('/some_route', function(){
      //pseudo code
    if (!p_db){
           MongoClient.connect(url, c_opt, function(err,db){
                  p_db = db;
                  p_db.collection("some_collection").findOne(doc, function(err,item){
                  if(err){
                      res.send(err);                          
                  }else{
                      //do something with item
                      res.send(item);
                  }

             });
           });
       }else {
          p_db.collection("some_collection").findOne(doc, function(err,item){
               if(err){
                      res.send(err);
                }else{
                      //do something with item
                      res.send(item);
                }

      });
    });

我几个月前阅读了Mongoose的源代码,他们为每个集合打开一个连接,因此它只是在变量中缓存。不确定他们是否进行了更改。 我编写了一个连接模块,并在app.listen之前运行它。 - wayne
2个回答

9

根据驱动程序主要贡献者的说法,最好在启动时连接数据库,并为每个请求重复使用同一连接。

mongodb原生驱动程序具有连接池,它在内部维护,并且当前默认最多打开5个连接。您可以通过maxPoolSize选项配置最大连接数。您还可以使用auto_reconnect选项配置连接以自动重新连接。

请参见此处的文档。


5

如果连接失败,驱动程序将尝试重新连接,您无需执行任何操作。在等待重新连接的过程中,它将缓冲之间发生的所有操作,并在连接恢复后重放它们。如果您想自己控制此过程,可以侦听 db 实例上的 "close" 事件并手动处理重新连接。重新连接时,db 对象仍然可用,因为 db 实际上只是共享连接池的包装器,不包含自己的独立连接逻辑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接