2012-03-20 22 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