用generic-pool连接的Mongodb, 运行大概一天后报这个错:
db object already connecting, open cannot be called multiple times
用了:cluster, generic-pool, mongodb, 它是运行一天后才出会现,而且访问的时候有些慢(其中有一个方法是查了4次mongodb);
我把这个方法(就是一个纯接口) 改成查2次,就没有这个问题了,而且也快了,为什么差别这么大?
pool是这么用的:
exports.dbpool = pool = poolModule.Pool({ name : 'mongo’, create : function(callback) { dbutil.createMongoClient('test’,function(err, db, client){ callback(err,client); }); }, destroy : function(client) { client.close(); }, max : 2, idleTimeoutMillis :100, log : false });
不知道这个配置是否有问题?
我在网上查了2天了,也没有查出正解;
请大拿们给正解; 谢谢;
其中有一个方法是查了4次mongodb
, 改成查2次,就没有这个问题了
和配置里面 max : 2
不觉得存在一定的因果关系吗。个人猜测这4次查询是并发,即几乎同一时间申请4个数据库连接,但是配置里面max = 2,于是乎。。。
PS: mongodb驱动自带连接池,外面有必要再套个generic-pool的连接池吗?
我用:max = 10 也会有同样的情况,只是刚开始较快一些,慢慢的就慢了,它还有一种比较奇怪的现象是:连续请求这个接口几次(基本上7次以内)后,会有一次不能响应的;然后再刷就又可以了(就是慢);
generic-pool的连接池是项目中在用,我暂时还不敢(我刚入门)把它去掉,因为这个模式已经跑一段时间了;
把能打开的日志全打开,跟踪连接池的连接数目出入,监视node的内存占用率(process.memoryUsage()),内存占用率一直增长却从不下降的话,很大可能是内存泄露(memory leak),有数据库连接没有被连接池回收。 可以的话,还是把api接口的代码贴出来吧,去掉业务逻辑,只保留数据库的相关操作
generic-pool我用了很长时间,没有你说的这个问题的,不知道你用的是哪个mongodb链接库,这个错误应该是你的mongodb库报的 原因可能是你实例化了一个mongodb连接,然后反复使用这个实例去连接数据库,伪代码可能如下:
var db = new mongodb('127.0.0.1',27017) //创建一个mongodb实例
db.connection()
db.connection() //反复调用connection,可能就会出现上面你说的错误.
所以使用generic-pool的注意:
- 连接使用完毕,一定要将连接放回连接池,不论是否有error错误
- 你在实例化连接池,注册create时,要保证里面的函数每次都是一个新实例,不要用单例,反复调用connect方法,这样就等于一个连接,还可能出错
- 注册create时,一定要根据api那样写,callback(err,db)err,这种
最后给你个地址,我用mongodb的native库配合generic-pool做的数据库连接文件,你可以参考哦 https://github.com/DoubleSpout/rrestjs/blob/master/lib/MongdbConnect.js
你的这个用 generic-pool 做 mongodb 的连接池,有遇到性能问题么?
我按照你的这个方便弄了一个, 压 1000并发, 60秒, 中间有的请求就没有响应了; 刷了几次后,发现又可以进行正常请求了!~
求真正原因?
@bao2dan 不知道你怎么压力测试的,mongodb和node是否装在一台机器上,机器配置如何?发包机器的网络环境,发包机器不能是跑node本机,本机压测自己没有意义。另外你是否有开测试机的监控,查看cpu和内存情况。我没发现你说的问题呀
@snoopy 我是用另一台虚拟机压的一台实机; mongodb和node不在一台机器上;
我调成下面这个参数后,以上问题出现的就少很多了: max : 50, idleTimeoutMillis :30000,
但我没有搞明白这两个参数对于性能的影响有多大?