generic-pool模块是nodejs的一个第三方模块,其作用为提供一个通用的连接池模块,可以通过generic-pool实现对tcp连接池或者mysql数据库连接池等的管理。github的地址如下:https://github.com/coopernurse/node-pool
其基本的使用方法可以参照作者给的例子。
// Create a MySQL connection pool with
// a max of 10 connections and a 30 second max idle time
var poolModule = require('generic-pool');
var pool = poolModule.Pool({
name : 'mysql',
create : function(callback) {
var Client = require('mysql').Client;
var c = new Client();
c.user = 'scott';
c.password = 'tiger';
c.database = 'mydb';
c.connect();
// parameter order: err, resource
// new in 1.0.6
callback(null, c);
},
destroy : function(client) { client.end(); },
max : 10,
idleTimeoutMillis : 30000,
log : true
});
// acquire connection - callback function is called
// once a resource becomes available
pool.acquire(function(err, client) {
client.query("select * from foo", [], function() {
// return object back to pool
pool.release(client);
});
});
示例的代码很简单。简要介绍一下。
name即该连接池的名称,这个变量用处不大。
create为一个函数对象,在该函数对象中需要给出连接建立的方法,变量c为连接句柄,通过c可以进行读写操作。callback(null,c)是必须有的,第一个参数可以是错误类型的变量,这样当连接建立错误时,不会把错误的连接进行计数。例如在创建连接时发生错误如果能触发error事件,那么callback可以改写成:
c.on("error",function(e){callback(e,c)});
callback(null,c);
destroy也是一个函数对象,实现的功能是释放连接句柄。
max为连接池中连接的最大数量。
idleTimeoutMills为连接失效时间,当一个连接的存活时间超过该失效时间时,连接会被销毁。
log为是否记录的标志符。
accquire即是对连接的调用。获取一个连接后,在回调函数中执行需要进行的逻辑。
generc-pool小巧精悍,总共只有几百行,完全由js代码写成。使用的方法页很简单。但是有一点不足的地方是,实例A和实例B建立链接,初始化连接池poolAB之后,如果实例A在守护进程的作用下进行了重启,此时poolAB中的所有连接都会失效,但是generic-pool本身只对超时的连接进行了处理,对于这种虽然没有超时但是已经失效的连接并没有相应操作。这个缺陷为我的工作带来了极大困扰。我对该模块进行了小小的改动,实现了对失效链接的处理。
其实就添加了一个函数:
function removeNotWritable() { var toKeep = [], i, al; // Go through the available (idle) items, // check if they are not writeable for (i = 0, al = availableObjects.length; i < al; i += 1) { if (availableObjects[i]["obj"]["writable"] != false && availableObjects[i]["obj"]["readable"] != false ) { // Client is writeable, so keep it. toKeep.push(availableObjects[i]); } else { // The client is not writeable, call it's destroyer. // log("removeIdle() destroying obj - now:" + now + "not writeable"); me.destroy(availableObjects[i].obj); } } // Replace the available items with the ones to keep. availableObjects = toKeep; al = availableObjects.length; }
这个函数遍历了连接池中所有现存的连接句柄,判断是否可读可写,若不可以,则证明该连接失效,删除此连接。在dispense()函数的如下位置调用该函数即可实现对失效连接的销毁。
function dispense() { ...... if (waitingCount > 0) { removeNotWritable(); if (availableObjects.length > 0) {