在一个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方法代码如下:
def establish_connection(name, spec)
@connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
end
对应上面Cookie模型的配置,这里name的值会是Cookie。也就是说,有10个模型中使用了establish_connection配置,@connection_pools中就会初始化10个ConnectionPool,如果每个ConnectionPool的pool size是20,那么应用运行的时候,将需要200(10 × 20)个数据库连接。而我的应用中有两类模型(连接到两个数据库),模型总数40+。按establish_connection的方式设置数据库连接,那么mysql的连接轻易就被消耗完了。
那要怎么处理呢?
我现在的思路是自己来维护数据库连接池。
首先,对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
分享到:
相关推荐
preserve_c_code_attention!!!_在linux下请慎用rm命令_删除了一堆代_c_code
- 在使用`preg_replace`时,将`$replacement`用单引号包围,如`'test("\1")'`,确保其被当作普通的字符串处理,而非PHP代码。 总而言之,虽然`preg_replace`配合`/e`修饰符在某些情况下能提供极大的便利,但是由于...
加密的惨剧!慎用文件夹加密软件! 加密的惨剧!慎用文件夹加密软件!
把要删除的文件拖到这个文件上面即可。注意,这是强力删除。一定慎用,因为连垃圾箱都会没有的。
SQL和MSDE清理小程序(慎用),SQL和MSDE清理小程序(慎用),SQL和MSDE清理小程序(慎用),
易语言处理事件命令慎用时钟版源码,处理事件命令慎用时钟版
慎用六大软件伤硬盘最终版.pdf
标题“慎用动态编译”指的是在编程过程中对动态编译这一技术的谨慎态度。动态编译是程序运行时根据需要将源代码编译为可执行代码的过程,与静态编译(编译时一次性完成)形成对比。在Java中,JIT(Just-In-Time)...
标题“慎用ext.zip”可能指的是在编程或系统管理中,对使用特定扩展名如“ext.zip”可能带来的潜在问题的警示。虽然描述部分没有提供具体信息,但我们可以基于这个标题来探讨一下在处理zip文件,特别是那些带有“ext...
玩客云 灯光控制 容易烧主板 慎用
慎用抗生素 刻不容缓 (小品).docx
《易语言处理事件命令慎用时钟版源码解析》 易语言,作为一款由中国程序员设计的编程语言,以其简洁的语法和贴近自然语言的特点,为初学者提供了友好的编程环境。然而,对于任何编程语言而言,理解并合理使用各种...
初中语文文摘生活慎用何首乌治白发
易语言处理事件命令慎用线程版源码。@易语言源码分享站。
标题中的“冰冻精灵清除器慎用.rar”指的是一个针对名为“冰冻精灵”软件的清除工具的压缩文件。冰冻精灵,也被称为Deep Freeze,是一款知名的系统还原软件,主要用于维护计算机系统的稳定状态,一旦系统出现问题,...
站长助手相关代码,里面有一点注入代码,慎用!!!
在敏捷开发中,慎用继承是一个非常重要的技巧,因为不恰当的继承使用可能导致代码的复杂性增加,维护难度提高。本文将深入探讨这个主题,以及如何在实际开发中合理运用继承。 继承是面向对象编程(OOP)中的一个...