精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-19
在一个Rails应用中连接多个数据库,我们常常这么做:
class Cookie < ActiveRecord::Base establish_connection :monitor_spider ... end
这样,在使用Cookie.find等操作的时候,就会连接到database.yml中monitor_spider配置的数据库上操作。 以前一直都这么用,没发现什么不妥。最近一个项目,由于启动的进程比较多,老是碰到数据库连接池链接获取超时的错误。通过MySQL Client用命令:show processlist; 发现数据库连接数量一直居高不下,轻轻松松就上2k+的连接。通过读Rails框架的connection_pool.rb文件代码,发现在各模型中用establish_connection连接数据库会造成很大的问题。文件中类ConnectionHandler的establish_connection方法代码如下:
那要怎么处理呢?
我现在的思路是自己来维护数据库连接池。
首先,对ConnectionAdapters进行一下改造,将如下代码放到initializers中:
module ActiveRecord module ConnectionAdapters class ConnectionHandler def specified_establish_connection(name, spec) @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec) end def retrieve_connection_pool(klass) if klass.respond_to?(:pool_name) pool = @connection_pools[klass.pool_name] # ActiveRecord::Base.logger.info "pool: #{pool.inspect}" return pool if pool end pool = @connection_pools[klass.name] # puts pool.inspect return pool if pool return nil if ActiveRecord::Base == klass retrieve_connection_pool klass.superclass end end end end
在environment.rb中事先连接建立数据库连接池:
#specified pool config = YAML::load(File.open("config/database.yml")) %w(monitor_center monitor_spider).each do |pool_name| spec = config[pool_name] adapter_method = "#{spec["adapter"]}_connection" ActiveRecord::Base.connection_handler.specified_establish_connection(pool_name, ActiveRecord::Base::ConnectionSpecification.new(spec, adapter_method)) end在模型中,定义方法pool_name:
class TaskStat < ActiveRecord::Base def self.pool_name;"monitor_spider";end ... end class TaskInfo < ActiveRecord::Base def self.pool_name;"monitor_center";end ... end
这样,TaskStat就会用monitor_spider pool,TaskInfo会用monitor_center pool。同时整个应用就只有三个ConnectionPool(外加默认的ActiveRecord::Base的) 通过这样的改造之后,效果明显,现在show processlist一般只有200~300的连接数。
首发:http://www.holin.info/posts/4c94cf27ff1f0146ef000002
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-09-30
不需要这么麻烦吧,你建立一个继承自ActiveRecord::Base的ExternalTable类,在ExternalTable类中使用establish_connection方法,其他需要使用外部表的model类都继承此ExternalTable类,就可以避免多个model连接数据库的问题了。
请参考RailsRecipe中的Recipe 15 |
|
返回顶楼 | |
发表时间:2010-10-01
这种的方案不错,还以为是楼主自创的……,不过分享还是的挺好的
|
|
返回顶楼 | |
发表时间:2010-10-03
sword0607 写道 不需要这么麻烦吧,你建立一个继承自ActiveRecord::Base的ExternalTable类,在ExternalTable类中使用establish_connection方法,其他需要使用外部表的model类都继承此ExternalTable类,就可以避免多个model连接数据库的问题了。
请参考RailsRecipe中的Recipe 15 的确是这样方便,之前没有看到这个内容,走了冤枉路。 |
|
返回顶楼 | |
发表时间:2010-10-10
一个疑问想问问楼主的场景:
database.yml中是有pool关键字的,类如: development: adapter: mysql2 encoding: utf8 reconnect: false database: flintstone_development pool: 5 username: root password: socket: /var/lib/mysql/mysql.sock 楼主的案例场景说发现很多链接,想问问这pool有没起作用。或者说并发限制有没受database.yml限制? |
|
返回顶楼 | |
发表时间:2010-10-11
xds2000 写道 一个疑问想问问楼主的场景:
database.yml中是有pool关键字的,类如: development: adapter: mysql2 encoding: utf8 reconnect: false database: flintstone_development pool: 5 username: root password: socket: /var/lib/mysql/mysql.sock 楼主的案例场景说发现很多链接,想问问这pool有没起作用。或者说并发限制有没受database.yml限制? pool参数就是设置的pool的大小。我这个案例场景里会实例化很多pool,所以导致链接过多。 ps: 我的应用是在Rails2.3版本下的,Rails3下并采用mysql2驱动我还不了解情况。 |
|
返回顶楼 | |
浏览 5708 次