2012-03-20 44 views
1

当我在我的服务器(运行node.js应用程序)上运行“lsof | grep node”时,我获得了大约1000多行(db连接到端口9160)。每行看起来像这样:Node.js lsof - 许多开放的数据库连接

node  17006  root 160u  IPv4   1362100969  0t0  TCP localhost:47813->localhost:9160 (ESTABLISHED) 

这是一个测试node.js服务器,做一些非常简单的事情。 (用Helenus模块将请求记录到Cassandra DB)

我很惊讶有这么多的开放式连接,当时肯定不应该有1-2个连接。

这是否意味着我不能在Node应用程序中正确结束我的数据库连接?我的代码如下。谢谢。

var express = require('express') 
, routes = require('./routes') 
, app = express.createServer(); 


     app.configure(function(){ 
         app.use(express.bodyParser()); 
         app.use(express.methodOverride()); 
         app.use(app.router); 
         }); 

     process.on('uncaughtException', function (err) { 
         logger.error('Caught exception: ' + err); 
         }); 

     function respond_test(req, res, next) { 
         var q = JSON.parse(req.query.q); 
         insert_db(q); 
         res.send('OK'); 
     } 

     function insert_db(q) { 
    var helenus = require('helenus'), 
      pool = new helenus.ConnectionPool({ 
       hosts  : ['localhost:9160'], 
        keyspace : 'Test', 
        timeout : 3000 
     }); 

    pool.on('error', function(err){ 
       logger.error(err.name, err.message); 
    }); 

      //makes a connection to the pool, this will return once there is at least one 
      //valid connection, other connections may still be pending 
      pool.connect(function(err, keyspace){ 
         if(err){ throw(err); } 

         keyspace.get('Test', function(err, cf){ 
             if(err){ throw(err);  } 
             cf.insert(Date.now(), q, function(err){ 
               if(err){ throw(err); } 
             }); 
         }); 
      }); 
    pool.close(); 
     } 

     app.get('/test', respond_test); 
     app.listen(80); 
+0

您可以发布您在您的应用中使用的代码吗? – 2012-03-20 18:07:00

+0

修改了一下这个问题。我看到它有很多连接到数据库(端口9160),而不是连接到Node.js服务器。谢谢 – awaage 2012-03-20 19:09:01

回答

2

您正在根据每个请求有效地连接和断开cassandra。游泳池旨在为您打开连接,因此您不必经常打开和关闭。这将大大提高您的性能,因为创建和销毁连接非常昂贵。我重构了一下你的代码,让你知道它应该如何使用。我在那里添加了一些评论以帮助您:

var express = require('express'), 
    routes = require('./routes'), 
    app = express.createServer(), 
    //define cf in this scope to be set once connected 
    test_cf; 


function respond_test(req, res, next) { 
    var q = JSON.parse(req.query.q); 

    test_cf.insert(Date.now(), q, function(err){ 
    if(err){ 
     res.send('ERROR'); 
     throw(err); 
    } else { 
    res.send('OK'); 
    } 
    }); 
} 

var helenus = require('helenus'), 
    pool = new helenus.ConnectionPool({ 
     hosts  : ['localhost:9160'], 
     keyspace : 'Test', 
     timeout : 3000 
    }); 

app.configure(function(){ 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(app.router); 
}); 

process.on('uncaughtException', function (err) { 
    logger.error('Caught exception: ' + err); 
}); 

pool.on('error', function(err){ 
    logger.error(err.name, err.message); 
}); 

pool.connect(function(err, keyspace){ 
    if(err){ 
    throw(err); 
    } 

    keyspace.get('Test', function(err, cf){ 
    if(err){ throw(err); } 
    test_cf = cf; 
    //don't start listening until connected 
    app.listen(80); 
    }); 
}); 

app.on('close', function(){ 
    //close the pool if we stop listening on http 
    pool.close(); 
}); 

app.get('/test', respond_test); 
2

因为在每次操作中您都会创建一个新池。您应该从池中获取连接,而不是每次都创建一个连接,这就是连接池比常规更有优势。游泳池的功能是打开一堆连接,然后保持它们为将来的请求而活着。

+0

我其实也试过,但也有同样的问题。我在顶部实例化了一次ConnectionPool,然后在insert_db()函数中,我只调用pool.connect(),然后调用pool.close()。这仍然导致很多很多连接(在ISA中)似乎不会消失。 – awaage 2012-03-20 21:06:47

+0

为什么你打电话关闭?你不需要关闭。 – Mustafa 2012-03-20 21:15:52

+0

我明白了..谢谢,我摆脱了关闭()的呼叫。但是,我仍然有大量连接打开,如lsof所示。这是预期的吗? – awaage 2012-03-20 21:34:25