前言
对于为什么要使用连接池,说白了就是降低系统开销,当我们在频繁创建和销毁的时候就会产生非常大的系统开销。
在我们平时使用时,没什么感觉,都是自己一个人用,系统开销非常小,但是当成百上千人在使用呢?而连接池的作用就是限制我们进行频繁的创建和销毁,使每次的访问都是之前已经创建好的,即重复利用。
好处:
1.可以不必为建立连接和释放连接消耗更多的响应时间,一个连接在高并发下可以被高度重用。
2.有队列机制,当池子中连接都用完了,其他请求在排队时,有一些紧急的任务需要插队,我们可以很方便的做到这点
安装方式
$ npm install generic-pool@3.8.2
创建
pool
,在对应字段填写对应redis
的host
,port
,user
,password
等信息
password
auth
授权信息,没有则不用写
// dao-pool.js
let genericPool = require('generic-pool');
let ioredis = require('ioredis');
let DEFAULT_MIN_POOL_SIZE = 5;
let DEFAULT_MAX_POOL_SIZE = 20;
let DEFAULT_IDLE_TIMEOUT_IN_MILLIS = 30 * 1000; //毫秒
/*
* 创建redis连接池
*/
module.exports = function () {
return genericPool.createPool({
name: 'redis',
create: function () {
return new ioredis({
port: '6379',
host: '127.0.0.1',
password: 'auth',
db: 0,
family: 4, // 4 (IPv4) or 6 (IPv6)
});
},
destroy: function (client) {
client.disconnect();
},
},{
max: DEFAULT_MAX_POOL_SIZE,
min: DEFAULT_MIN_POOL_SIZE,
idleTimeoutMillis: DEFAULT_IDLE_TIMEOUT_IN_MILLIS,
priorityRange: 3,
log: false
});
};
Redis
对pool
的封装使用
opt
正常回调操作redis
数据promiseOpt
异步promise
操作redis
数据,新手可以忽略。
// redis.js
let redisclient = module.exports;
let _pool;
let NND = {};
NND.init = function () {
_pool = require('./dao-pool')();
};
/**
* 获取redis client并执行对应redis命令
*/
NND.opt = function () {
let args = Array.prototype.slice.call(arguments);
_pool.acquire().then(function (client) {
let cmd = args[0];
let key, val, val2, val3, cb;
switch (cmd) {
case 'pipeline':
val = args[1]; // 数组 [[cmd1, key1, val1],[cmd2, key2]]
cb = args[2];
client.pipeline(val).exec(function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'get':
key = args[1];
cb = args[2];
client.get(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'set':
key = args[1];
val = args[2];
cb = args[3];
client.set(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'incr':
key = args[1];
cb = args[2];
client.incr(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'incrby':
key = args[1];
val = args[2];
cb = args[3];
client.incrby(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'lpush':
key = args[1];
val = args[2];
cb = args[3];
client.lpush(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'lset':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.lset(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'lrange':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.lrange(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hset':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.hset(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hmset':
key = args[1];
val = args[2];
cb = args[3];
client.hmset(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hget':
key = args[1];
val = args[2];
cb = args[3];
client.hget(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hgetall':
key = args[1];
cb = args[2];
client.hgetall(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hincrby':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.hincrby(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'expire':
key = args[1];
val = args[2];
cb = args[3];
client.expire(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'sadd':
key = args[1];
val = args[2];
cb = args[3];
client.sadd(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'sismember':
key = args[1];
val = args[2];
cb = args[3];
client.sismember(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'smembers':
key = args[1];
cb = args[2];
client.smembers(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'scard':
key = args[1];
cb = args[2];
client.scard(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zadd':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.zadd(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zcard':
key = args[1];
cb = args[2];
client.zcard(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zrevrange':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.zrevrange(key, val, val2, 'WITHSCORES', function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zrem':
key = args[1];
val = args[2];
cb = args[3];
client.zrem(key, val, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zremrangebyrank':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.zremrangebyrank(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'zincrby':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.zincrby(key, val, val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'hscan':
key = args[1];
val = args[2];
val2 = args[3];
cb = args[4];
client.hscan(key, val, 'count', val2, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'del':
key = args[1];
cb = args[2];
client.del(key, function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
case 'bgsave':
cb = args[1];
client.bgsave(function (err, res) {
_pool.release(client);
cb && cb(err, res);
});
break;
}
}).catch(function (err) {
console.error(err.stack);
});
};
/**
* 封装 Promise
* @returns {Promise<any>}
*/
NND.promiseOpt = function() {
return new Promise((resolve)=>{
NND.opt(...arguments, function (err, reply) {
if (err){
resolve({
code: 500,
msg: err.message
});
} else {
resolve({
code: 200,
reply: reply
});
}
});
});
};
/**
* 销毁连接池
*/
NND.shutdown = function () {
_pool.drain().then(function () {
_pool.clear();
});
};
redisclient.init = function () {
if (!!_pool) {
return redisclient;
} else {
NND.init();
redisclient.opt = NND.opt;
redisclient.promiseOpt = NND.promiseOpt;
return redisclient;
}
};
redisclient.shutdown = function () {
NND.shutdown();
};
结束
大致使用方式,就是这样,做个记录方便自己以后使用,具体使用情况可以根据自己情况修改。